]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_pbr.c
Merge pull request #3785 from qlyoung/fix-aspath-prepend-heap-uaf-6.0.3
[mirror_frr.git] / bgpd / bgp_pbr.c
index 615b5723c42b3f4e286871640123d3f48e0f51a4..b182fde1e2ec5d0d495be6f7dd152ab993b26623 100644 (file)
@@ -33,6 +33,7 @@
 #include "bgpd/bgp_zebra.h"
 #include "bgpd/bgp_mplsvpn.h"
 #include "bgpd/bgp_flowspec_private.h"
+#include "bgpd/bgp_errors.h"
 
 DEFINE_MTYPE_STATIC(BGPD, PBR_MATCH_ENTRY, "PBR match entry")
 DEFINE_MTYPE_STATIC(BGPD, PBR_MATCH, "PBR match")
@@ -230,6 +231,47 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
                                                  struct bgp_pbr_filter *bpf,
                                                  struct nexthop *nh,
                                                  float *rate);
+
+static void bgp_pbr_dump_entry(struct bgp_pbr_filter *bpf, bool add);
+
+static bool bgp_pbr_extract_enumerate_unary_opposite(
+                                uint8_t unary_operator,
+                                struct bgp_pbr_val_mask *and_valmask,
+                                struct list *or_valmask, uint32_t value,
+                                uint8_t type_entry)
+{
+       if (unary_operator == OPERATOR_UNARY_AND && and_valmask) {
+               if (type_entry == FLOWSPEC_TCP_FLAGS) {
+                       and_valmask->mask |=
+                               TCP_HEADER_ALL_FLAGS &
+                               ~(value);
+               } else if (type_entry == FLOWSPEC_DSCP ||
+                          type_entry == FLOWSPEC_PKT_LEN ||
+                          type_entry == FLOWSPEC_FRAGMENT) {
+                       and_valmask->val = value;
+                       and_valmask->mask = 1; /* inverse */
+               }
+       } else if (unary_operator == OPERATOR_UNARY_OR && or_valmask) {
+               and_valmask = XCALLOC(MTYPE_PBR_VALMASK,
+                                     sizeof(struct bgp_pbr_val_mask));
+               if (type_entry == FLOWSPEC_TCP_FLAGS) {
+                       and_valmask->val = TCP_HEADER_ALL_FLAGS;
+                       and_valmask->mask |=
+                               TCP_HEADER_ALL_FLAGS &
+                               ~(value);
+               } else if (type_entry == FLOWSPEC_DSCP ||
+                          type_entry == FLOWSPEC_FRAGMENT ||
+                          type_entry == FLOWSPEC_PKT_LEN) {
+                       and_valmask->val = value;
+                       and_valmask->mask = 1; /* inverse */
+               }
+               listnode_add(or_valmask, and_valmask);
+       } else if (type_entry == FLOWSPEC_ICMP_CODE ||
+                  type_entry == FLOWSPEC_ICMP_TYPE)
+               return false;
+       return true;
+}
+
 /* TCP : FIN and SYN -> val = ALL; mask = 3
  * TCP : not (FIN and SYN) -> val = ALL; mask = ALL & ~(FIN|RST)
  * other variables type: dscp, pkt len, fragment
@@ -243,6 +285,7 @@ static bool bgp_pbr_extract_enumerate_unary(struct bgp_pbr_match_val list[],
        int i = 0;
        struct bgp_pbr_val_mask *and_valmask = NULL;
        struct list *or_valmask = NULL;
+       bool ret;
 
        if (valmask) {
                if (unary_operator == OPERATOR_UNARY_AND) {
@@ -264,35 +307,12 @@ static bool bgp_pbr_extract_enumerate_unary(struct bgp_pbr_match_val list[],
                             OPERATOR_COMPARE_LESS_THAN) &&
                            (list[i].compare_operator &
                             OPERATOR_COMPARE_GREATER_THAN)) {
-                               if (unary_operator == OPERATOR_UNARY_AND && and_valmask) {
-                                       if (type_entry == FLOWSPEC_TCP_FLAGS) {
-                                               and_valmask->mask |=
-                                                       TCP_HEADER_ALL_FLAGS &
-                                                       ~(list[i].value);
-                                       } else if (type_entry == FLOWSPEC_DSCP ||
-                                                  type_entry == FLOWSPEC_PKT_LEN ||
-                                                  type_entry == FLOWSPEC_FRAGMENT) {
-                                               and_valmask->val = list[i].value;
-                                               and_valmask->mask = 1; /* inverse */
-                                       }
-                               } else if (unary_operator == OPERATOR_UNARY_OR && or_valmask) {
-                                       and_valmask = XCALLOC(MTYPE_PBR_VALMASK,
-                                                             sizeof(struct bgp_pbr_val_mask));
-                                       if (type_entry == FLOWSPEC_TCP_FLAGS) {
-                                               and_valmask->val = TCP_HEADER_ALL_FLAGS;
-                                               and_valmask->mask |=
-                                                       TCP_HEADER_ALL_FLAGS &
-                                                       ~(list[i].value);
-                                       } else if (type_entry == FLOWSPEC_DSCP ||
-                                                  type_entry == FLOWSPEC_FRAGMENT ||
-                                                  type_entry == FLOWSPEC_PKT_LEN) {
-                                               and_valmask->val = list[i].value;
-                                               and_valmask->mask = 1; /* inverse */
-                                       }
-                                       listnode_add (or_valmask, and_valmask);
-                               } else if (type_entry == FLOWSPEC_ICMP_CODE ||
-                                          type_entry == FLOWSPEC_ICMP_TYPE)
-                                       return false;
+                               ret = bgp_pbr_extract_enumerate_unary_opposite(
+                                                unary_operator, and_valmask,
+                                                or_valmask, list[i].value,
+                                                type_entry);
+                               if (ret == false)
+                                       return ret;
                                continue;
                        }
                        return false;
@@ -331,7 +351,7 @@ static bool bgp_pbr_extract_enumerate(struct bgp_pbr_match_val list[],
                                      void *valmask, uint8_t type_entry)
 {
        bool ret;
-       uint8_t unary_operator_val = unary_operator;
+       uint8_t unary_operator_val;
        bool double_check = false;
 
        if ((unary_operator & OPERATOR_UNARY_OR) &&
@@ -633,8 +653,9 @@ static int bgp_pbr_build_and_validate_entry(struct prefix *p,
                        action_count++;
                        if (action_count > ACTIONS_MAX_NUM) {
                                if (BGP_DEBUG(pbr, PBR_ERROR))
-                                       zlog_err("%s: flowspec actions exceeds limit (max %u)",
-                                                __func__, action_count);
+                                       flog_err(BGP_ERR_FLOWSPEC_PACKET,
+                                                 "%s: flowspec actions exceeds limit (max %u)",
+                                                 __func__, action_count);
                                break;
                        }
                        api_action = &api->actions[action_count - 1];
@@ -816,12 +837,12 @@ uint32_t bgp_pbr_match_hash_key(void *arg)
 
        key = jhash_1word(pbm->vrf_id, 0x4312abde);
        key = jhash_1word(pbm->flags, key);
-       key = jhash_1word(pbm->pkt_len_min, key);
-       key = jhash_1word(pbm->pkt_len_max, key);
-       key = jhash_1word(pbm->tcp_flags, key);
-       key = jhash_1word(pbm->tcp_mask_flags, key);
-       key = jhash_1word(pbm->dscp_value, key);
-       key = jhash_1word(pbm->fragment, key);
+       key = jhash(&pbm->pkt_len_min, 2, key);
+       key = jhash(&pbm->pkt_len_max, 2, key);
+       key = jhash(&pbm->tcp_flags, 2, key);
+       key = jhash(&pbm->tcp_mask_flags, 2, key);
+       key = jhash(&pbm->dscp_value, 1, key);
+       key = jhash(&pbm->fragment, 1, key);
        return jhash_1word(pbm->type, key);
 }
 
@@ -1208,7 +1229,8 @@ static void bgp_pbr_flush_entry(struct bgp *bgp, struct bgp_pbr_action *bpa,
                        /* unlink bgp_info to bpme */
                        bgp_info = (struct bgp_info *)bpme->bgp_info;
                        extra = bgp_info_extra_get(bgp_info);
-                       extra->bgp_fs_pbr = NULL;
+                       if (extra->bgp_fs_pbr)
+                               listnode_delete(extra->bgp_fs_pbr, bpme);
                        bpme->bgp_info = NULL;
                }
        }
@@ -1265,7 +1287,13 @@ static int bgp_pbr_get_remaining_entry(struct hash_backet *backet, void *arg)
        bpm_temp = bpme->backpointer;
        if (bpm_temp->vrf_id != bpm->vrf_id ||
            bpm_temp->type != bpm->type ||
-           bpm_temp->flags != bpm->flags)
+           bpm_temp->flags != bpm->flags ||
+           bpm_temp->tcp_flags != bpm->tcp_flags ||
+           bpm_temp->tcp_mask_flags != bpm->tcp_mask_flags ||
+           bpm_temp->pkt_len_min != bpm->pkt_len_min ||
+           bpm_temp->pkt_len_max != bpm->pkt_len_max ||
+           bpm_temp->dscp_value != bpm->dscp_value ||
+           bpm_temp->fragment != bpm->fragment)
                return HASHWALK_CONTINUE;
 
        /* look for remaining bpme */
@@ -1294,6 +1322,9 @@ static void bgp_pbr_policyroute_remove_from_zebra_unit(struct bgp *bgp,
        dst_port = bpf->dst_port;
        pkt_len = bpf->pkt_len;
 
+       if (BGP_DEBUG(zebra, ZEBRA))
+               bgp_pbr_dump_entry(bpf, false);
+
        /* as we don't know information from EC
         * look for bpm that have the bpm
         * with vrf_id characteristics
@@ -1310,7 +1341,9 @@ static void bgp_pbr_policyroute_remove_from_zebra_unit(struct bgp *bgp,
                prefix_copy(&temp2.dst, bpf->dst);
        } else
                temp2.dst.family = AF_INET;
-       if (src_port && src_port->min_port) {
+       if (src_port && (src_port->min_port || bpf->protocol == IPPROTO_ICMP)) {
+               if (bpf->protocol == IPPROTO_ICMP)
+                       temp.flags |= MATCH_ICMP_SET;
                temp.flags |= MATCH_PORT_SRC_SET;
                temp2.src_port_min = src_port->min_port;
                if (src_port->max_port) {
@@ -1318,7 +1351,9 @@ static void bgp_pbr_policyroute_remove_from_zebra_unit(struct bgp *bgp,
                        temp2.src_port_max = src_port->max_port;
                }
        }
-       if (dst_port && dst_port->min_port) {
+       if (dst_port && (dst_port->min_port || bpf->protocol == IPPROTO_ICMP)) {
+               if (bpf->protocol == IPPROTO_ICMP)
+                       temp.flags |= MATCH_ICMP_SET;
                temp.flags |= MATCH_PORT_DST_SET;
                temp2.dst_port_min = dst_port->min_port;
                if (dst_port->max_port) {
@@ -1560,6 +1595,101 @@ static void bgp_pbr_policyroute_remove_from_zebra(struct bgp *bgp,
                list_delete_all_node(bpof->fragment);
 }
 
+static void bgp_pbr_dump_entry(struct bgp_pbr_filter *bpf, bool add)
+{
+       struct bgp_pbr_range_port *src_port;
+       struct bgp_pbr_range_port *dst_port;
+       struct bgp_pbr_range_port *pkt_len;
+       char bufsrc[64], bufdst[64];
+       char buffer[64];
+       int remaining_len = 0;
+       char protocol_str[16];
+
+       if (!bpf)
+               return;
+       src_port = bpf->src_port;
+       dst_port = bpf->dst_port;
+       pkt_len = bpf->pkt_len;
+
+       protocol_str[0] = '\0';
+       if (bpf->tcp_flags && bpf->tcp_flags->mask)
+               bpf->protocol = IPPROTO_TCP;
+       if (bpf->protocol)
+               snprintf(protocol_str, sizeof(protocol_str),
+                        "proto %d", bpf->protocol);
+       buffer[0] = '\0';
+       if (bpf->protocol == IPPROTO_ICMP && src_port && dst_port)
+               remaining_len += snprintf(buffer, sizeof(buffer),
+                                         "type %d, code %d",
+                                         src_port->min_port,
+                                         dst_port->min_port);
+       else if (bpf->protocol == IPPROTO_UDP ||
+                bpf->protocol == IPPROTO_TCP) {
+
+               if (src_port && src_port->min_port)
+                       remaining_len += snprintf(buffer,
+                                                 sizeof(buffer),
+                                                 "from [%u:%u]",
+                                                 src_port->min_port,
+                                                 src_port->max_port ?
+                                                 src_port->max_port :
+                                                 src_port->min_port);
+               if (dst_port && dst_port->min_port)
+                       remaining_len += snprintf(buffer +
+                                                 remaining_len,
+                                                 sizeof(buffer)
+                                                 - remaining_len,
+                                                 "to [%u:%u]",
+                                                 dst_port->min_port,
+                                                 dst_port->max_port ?
+                                                 dst_port->max_port :
+                                                 dst_port->min_port);
+       }
+       if (pkt_len && (pkt_len->min_port || pkt_len->max_port)) {
+               remaining_len += snprintf(buffer + remaining_len,
+                                         sizeof(buffer)
+                                         - remaining_len,
+                                         " len [%u:%u]",
+                                         pkt_len->min_port,
+                                         pkt_len->max_port ?
+                                         pkt_len->max_port :
+                                         pkt_len->min_port);
+       } else if (bpf->pkt_len_val) {
+               remaining_len += snprintf(buffer + remaining_len,
+                                         sizeof(buffer)
+                                         - remaining_len,
+                                         " %s len %u",
+                                         bpf->pkt_len_val->mask
+                                         ? "!" : "",
+                                         bpf->pkt_len_val->val);
+       }
+       if (bpf->tcp_flags) {
+               remaining_len += snprintf(buffer + remaining_len,
+                                         sizeof(buffer)
+                                         - remaining_len,
+                                         "tcpflags %x/%x",
+                                         bpf->tcp_flags->val,
+                                         bpf->tcp_flags->mask);
+       }
+       if (bpf->dscp) {
+               snprintf(buffer + remaining_len,
+                        sizeof(buffer)
+                        - remaining_len,
+                        "%s dscp %d",
+                        bpf->dscp->mask
+                        ? "!" : "",
+                        bpf->dscp->val);
+       }
+       zlog_debug("BGP: %s FS PBR from %s to %s, %s %s",
+                 add ? "adding" : "removing",
+                 bpf->src == NULL ? "<all>" :
+                 prefix2str(bpf->src, bufsrc, sizeof(bufsrc)),
+                 bpf->dst == NULL ? "<all>" :
+                 prefix2str(bpf->dst, bufdst, sizeof(bufdst)),
+                 protocol_str, buffer);
+
+}
+
 static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
                                     struct bgp_info *binfo,
                                     struct bgp_pbr_filter *bpf,
@@ -1576,6 +1706,7 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
        struct bgp_pbr_range_port *src_port;
        struct bgp_pbr_range_port *dst_port;
        struct bgp_pbr_range_port *pkt_len;
+       bool bpme_found = false;
 
        if (!bpf)
                return;
@@ -1583,87 +1714,9 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
        dst_port = bpf->dst_port;
        pkt_len = bpf->pkt_len;
 
-       if (BGP_DEBUG(zebra, ZEBRA)) {
-               char bufsrc[64], bufdst[64];
-               char buffer[64];
-               int remaining_len = 0;
-               char protocol_str[16];
-
-               protocol_str[0] = '\0';
-               if (bpf->tcp_flags && bpf->tcp_flags->mask)
-                       bpf->protocol = IPPROTO_TCP;
-               if (bpf->protocol)
-                       snprintf(protocol_str, sizeof(protocol_str),
-                                "proto %d", bpf->protocol);
-               buffer[0] = '\0';
-               if (bpf->protocol == IPPROTO_ICMP && src_port && dst_port)
-                       remaining_len += snprintf(buffer, sizeof(buffer),
-                                                 "type %d, code %d",
-                                src_port->min_port, dst_port->min_port);
-               else if (bpf->protocol == IPPROTO_UDP ||
-                        bpf->protocol == IPPROTO_TCP) {
-
-                       if (src_port && src_port->min_port)
-                               remaining_len += snprintf(buffer,
-                                                         sizeof(buffer),
-                                                         "from [%u:%u]",
-                                                         src_port->min_port,
-                                                         src_port->max_port ?
-                                                         src_port->max_port :
-                                                         src_port->min_port);
-                       if (dst_port && dst_port->min_port)
-                               remaining_len += snprintf(buffer +
-                                                         remaining_len,
-                                                         sizeof(buffer)
-                                                         - remaining_len,
-                                                         "to [%u:%u]",
-                                                         dst_port->min_port,
-                                                         dst_port->max_port ?
-                                                         dst_port->max_port :
-                                                         dst_port->min_port);
-               }
-               if (pkt_len && (pkt_len->min_port || pkt_len->max_port)) {
-                       remaining_len += snprintf(buffer + remaining_len,
-                                                 sizeof(buffer)
-                                                 - remaining_len,
-                                                 " len [%u:%u]",
-                                                 pkt_len->min_port,
-                                                 pkt_len->max_port ?
-                                                 pkt_len->max_port :
-                                                 pkt_len->min_port);
-               } else if (bpf->pkt_len_val) {
-                       remaining_len += snprintf(buffer + remaining_len,
-                                                 sizeof(buffer)
-                                                 - remaining_len,
-                                                 " %s len %u",
-                                                 bpf->pkt_len_val->mask
-                                                 ? "!" : "",
-                                                 bpf->pkt_len_val->val);
-               }
-               if (bpf->tcp_flags) {
-                       remaining_len += snprintf(buffer + remaining_len,
-                                                 sizeof(buffer)
-                                                 - remaining_len,
-                                                 "tcpflags %x/%x",
-                                                 bpf->tcp_flags->val,
-                                                 bpf->tcp_flags->mask);
-               }
-               if (bpf->dscp) {
-                       snprintf(buffer + remaining_len,
-                                sizeof(buffer)
-                                - remaining_len,
-                                "%s dscp %d",
-                                bpf->dscp->mask
-                                ? "!" : "",
-                                bpf->dscp->val);
-               }
-               zlog_info("BGP: adding FS PBR from %s to %s, %s %s",
-                         bpf->src == NULL ? "<all>" :
-                         prefix2str(bpf->src, bufsrc, sizeof(bufsrc)),
-                         bpf->dst == NULL ? "<all>" :
-                         prefix2str(bpf->dst, bufdst, sizeof(bufdst)),
-                         protocol_str, buffer);
-       }
+       if (BGP_DEBUG(zebra, ZEBRA))
+               bgp_pbr_dump_entry(bpf, true);
+
        /* look for bpa first */
        memset(&temp3, 0, sizeof(temp3));
        if (rate)
@@ -1692,33 +1745,38 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
 
        /* then look for bpm */
        memset(&temp, 0, sizeof(temp));
-       if (bpf->src == NULL || bpf->dst == NULL) {
-               if ((src_port && src_port->min_port) ||
-                   (dst_port && dst_port->min_port))
-                       temp.type = IPSET_NET_PORT;
-               else
-                       temp.type = IPSET_NET;
-       } else {
-               if ((src_port && src_port->min_port) ||
-                   (dst_port && dst_port->min_port))
-                       temp.type = IPSET_NET_PORT_NET;
-               else
-                       temp.type = IPSET_NET_NET;
-       }
        temp.vrf_id = bpf->vrf_id;
        if (bpf->src)
                temp.flags |= MATCH_IP_SRC_SET;
        if (bpf->dst)
                temp.flags |= MATCH_IP_DST_SET;
 
-       if (src_port && src_port->min_port)
+       if (src_port && (src_port->min_port || bpf->protocol == IPPROTO_ICMP)) {
+               if (bpf->protocol == IPPROTO_ICMP)
+                       temp.flags |= MATCH_ICMP_SET;
                temp.flags |= MATCH_PORT_SRC_SET;
-       if (dst_port && dst_port->min_port)
+       }
+       if (dst_port && (dst_port->min_port || bpf->protocol == IPPROTO_ICMP)) {
+               if (bpf->protocol == IPPROTO_ICMP)
+                       temp.flags |= MATCH_ICMP_SET;
                temp.flags |= MATCH_PORT_DST_SET;
+       }
        if (src_port && src_port->max_port)
                temp.flags |= MATCH_PORT_SRC_RANGE_SET;
        if (dst_port && dst_port->max_port)
                temp.flags |= MATCH_PORT_DST_RANGE_SET;
+
+       if (bpf->src == NULL || bpf->dst == NULL) {
+               if (temp.flags & (MATCH_PORT_DST_SET | MATCH_PORT_SRC_SET))
+                       temp.type = IPSET_NET_PORT;
+               else
+                       temp.type = IPSET_NET;
+       } else {
+               if (temp.flags & (MATCH_PORT_DST_SET | MATCH_PORT_SRC_SET))
+                       temp.type = IPSET_NET_PORT_NET;
+               else
+                       temp.type = IPSET_NET_NET;
+       }
        if (pkt_len) {
                temp.pkt_len_min = pkt_len->min_port;
                if (pkt_len->max_port)
@@ -1749,7 +1807,7 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
                       bgp_pbr_match_alloc_intern);
 
        /* new, then self allocate ipset_name and unique */
-       if (bpm && bpm->unique == 0) {
+       if (bpm->unique == 0) {
                bpm->unique = ++bgp_pbr_match_counter_unique;
                /* 0 value is forbidden */
                sprintf(bpm->ipset_name, "match%p", bpm);
@@ -1780,10 +1838,9 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
        temp2.src_port_max = src_port ? src_port->max_port : 0;
        temp2.dst_port_max = dst_port ? dst_port->max_port : 0;
        temp2.proto = bpf->protocol;
-       if (bpm)
-               bpme = hash_get(bpm->entry_hash, &temp2,
-                               bgp_pbr_match_entry_alloc_intern);
-       if (bpme && bpme->unique == 0) {
+       bpme = hash_get(bpm->entry_hash, &temp2,
+                       bgp_pbr_match_entry_alloc_intern);
+       if (bpme->unique == 0) {
                bpme->unique = ++bgp_pbr_match_entry_counter_unique;
                /* 0 value is forbidden */
                bpme->backpointer = bpm;
@@ -1791,8 +1848,21 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
                bpme->install_in_progress = false;
                /* link bgp info to bpme */
                bpme->bgp_info = (void *)binfo;
-       }
+       } else
+               bpme_found = true;
 
+       /* already installed */
+       if (bpme_found) {
+               struct bgp_info_extra *extra = bgp_info_extra_get(binfo);
+
+               if (extra && extra->bgp_fs_pbr &&
+                   listnode_lookup(extra->bgp_fs_pbr, bpme)) {
+                       if (BGP_DEBUG(pbr, PBR_ERROR))
+                               zlog_err("%s: entry %p/%p already installed in bgp pbr",
+                                        __func__, binfo, bpme);
+                       return;
+               }
+       }
        /* BGP FS: append entry to zebra
         * - policies are not routing entries and as such
         * route replace semantics don't necessarily follow
@@ -2169,7 +2239,6 @@ void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p,
                         bool nlri_update)
 {
        struct bgp_pbr_entry_main api;
-       struct bgp_info_extra *extra = bgp_info_extra_get(info);
 
        if (afi == AFI_IP6)
                return; /* IPv6 not supported */
@@ -2182,22 +2251,17 @@ void bgp_pbr_update_entry(struct bgp *bgp, struct prefix *p,
 
        if (!bgp_zebra_tm_chunk_obtained()) {
                if (BGP_DEBUG(pbr, PBR_ERROR))
-                       zlog_err("%s: table chunk not obtained yet",
-                                __func__);
-               return;
-       }
-       /* already installed */
-       if (nlri_update && extra->bgp_fs_pbr) {
-               if (BGP_DEBUG(pbr, PBR_ERROR))
-                       zlog_err("%s: entry %p already installed in bgp pbr",
-                                __func__, info);
+                       flog_err(BGP_ERR_TABLE_CHUNK,
+                                 "%s: table chunk not obtained yet",
+                                 __func__);
                return;
        }
 
        if (bgp_pbr_build_and_validate_entry(p, info, &api) < 0) {
                if (BGP_DEBUG(pbr, PBR_ERROR))
-                       zlog_err("%s: cancel updating entry %p in bgp pbr",
-                                __func__, info);
+                       flog_err(BGP_ERR_FLOWSPEC_INSTALLATION,
+                                 "%s: cancel updating entry %p in bgp pbr",
+                                 __func__, info);
                return;
        }
        bgp_pbr_handle_entry(bgp, info, &api, nlri_update);