back to topotato report
topotato coverage report
Current view: top level - bgpd - bgp_flowspec_util.c (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 0 363 0.0 %
Date: 2023-02-24 19:38:44 Functions: 0 8 0.0 %

          Line data    Source code
       1             : /* BGP FlowSpec Utilities
       2             :  * Portions:
       3             :  *     Copyright (C) 2017 ChinaTelecom SDN Group
       4             :  *     Copyright (C) 2018 6WIND
       5             :  *
       6             :  * FRRouting is free software; you can redistribute it and/or modify it
       7             :  * under the terms of the GNU General Public License as published by the
       8             :  * Free Software Foundation; either version 2, or (at your option) any
       9             :  * later version.
      10             :  *
      11             :  * FRRouting is distributed in the hope that it will be useful, but
      12             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License along
      17             :  * with this program; see the file COPYING; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include "zebra.h"
      22             : 
      23             : #include "lib/printfrr.h"
      24             : 
      25             : #include "prefix.h"
      26             : #include "lib_errors.h"
      27             : 
      28             : #include "bgp_route.h"
      29             : #include "bgp_table.h"
      30             : #include "bgp_flowspec_util.h"
      31             : #include "bgp_flowspec_private.h"
      32             : #include "bgp_pbr.h"
      33             : #include "bgp_errors.h"
      34             : 
      35           0 : static void hex2bin(uint8_t *hex, int *bin)
      36             : {
      37           0 :         int remainder = *hex;
      38           0 :         int i = 0;
      39             : 
      40           0 :         while (remainder >= 1 && i < 8) {
      41           0 :                 bin[7-i] = remainder % 2;
      42           0 :                 remainder = remainder / 2;
      43           0 :                 i++;
      44             :         }
      45           0 :         for (; i < 8; i++)
      46           0 :                 bin[7-i] = 0;
      47           0 : }
      48             : 
      49           0 : static int hexstr2num(uint8_t *hexstr, int len)
      50             : {
      51           0 :         int i = 0;
      52           0 :         int num = 0;
      53             : 
      54           0 :         for (i = 0; i < len; i++)
      55           0 :                 num = hexstr[i] + 16*16*num;
      56           0 :         return num;
      57             : }
      58             : 
      59             : /* call bgp_flowspec_op_decode
      60             :  * returns offset
      61             :  */
      62           0 : static int bgp_flowspec_call_non_opaque_decode(uint8_t *nlri_content, int len,
      63             :                                                struct bgp_pbr_match_val *mval,
      64             :                                                uint8_t *match_num, int *error)
      65             : {
      66           0 :         int ret;
      67             : 
      68           0 :         ret = bgp_flowspec_op_decode(
      69             :                              BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE,
      70             :                              nlri_content,
      71             :                              len,
      72             :                              mval, error);
      73           0 :         if (*error < 0)
      74           0 :                 flog_err(EC_BGP_FLOWSPEC_PACKET,
      75             :                          "%s: flowspec_op_decode error %d", __func__, *error);
      76             :         else
      77           0 :                 *match_num = *error;
      78           0 :         return ret;
      79             : }
      80             : 
      81             : 
      82           0 : bool bgp_flowspec_contains_prefix(const struct prefix *pfs,
      83             :                                   struct prefix *input, int prefix_check)
      84             : {
      85           0 :         uint32_t offset = 0;
      86           0 :         int type;
      87           0 :         int ret = 0, error = 0;
      88           0 :         uint8_t *nlri_content = (uint8_t *)pfs->u.prefix_flowspec.ptr;
      89           0 :         size_t len = pfs->u.prefix_flowspec.prefixlen;
      90           0 :         afi_t afi = family2afi(pfs->u.prefix_flowspec.family);
      91           0 :         struct prefix compare;
      92             : 
      93           0 :         error = 0;
      94           0 :         while (offset < len-1 && error >= 0) {
      95           0 :                 type = nlri_content[offset];
      96           0 :                 offset++;
      97           0 :                 switch (type) {
      98           0 :                 case FLOWSPEC_DEST_PREFIX:
      99             :                 case FLOWSPEC_SRC_PREFIX:
     100           0 :                         memset(&compare, 0, sizeof(compare));
     101           0 :                         ret = bgp_flowspec_ip_address(
     102             :                                         BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE,
     103             :                                         nlri_content+offset,
     104             :                                         len - offset,
     105             :                                         &compare, &error,
     106             :                                         afi, NULL);
     107           0 :                         if (ret <= 0)
     108             :                                 break;
     109           0 :                         if (prefix_check &&
     110           0 :                             compare.prefixlen != input->prefixlen)
     111             :                                 break;
     112           0 :                         if (compare.family != input->family)
     113             :                                 break;
     114           0 :                         if ((input->family == AF_INET) &&
     115           0 :                             IPV4_ADDR_SAME(&input->u.prefix4,
     116             :                                            &compare.u.prefix4))
     117             :                                 return true;
     118           0 :                         if ((input->family == AF_INET6) &&
     119           0 :                             IPV6_ADDR_SAME(&input->u.prefix6.s6_addr,
     120             :                                            &compare.u.prefix6.s6_addr))
     121             :                                 return true;
     122             :                         break;
     123           0 :                 case FLOWSPEC_FLOW_LABEL:
     124           0 :                         if (afi == AFI_IP) {
     125           0 :                                 error = -1;
     126           0 :                                 continue;
     127             :                         }
     128           0 :                         ret = bgp_flowspec_op_decode(BGP_FLOWSPEC_VALIDATE_ONLY,
     129             :                                                      nlri_content+offset,
     130             :                                                      len - offset,
     131             :                                                      NULL, &error);
     132           0 :                         break;
     133           0 :                 case FLOWSPEC_IP_PROTOCOL:
     134             :                 case FLOWSPEC_PORT:
     135             :                 case FLOWSPEC_DEST_PORT:
     136             :                 case FLOWSPEC_SRC_PORT:
     137             :                 case FLOWSPEC_ICMP_TYPE:
     138             :                 case FLOWSPEC_ICMP_CODE:
     139           0 :                         ret = bgp_flowspec_op_decode(BGP_FLOWSPEC_VALIDATE_ONLY,
     140             :                                                      nlri_content+offset,
     141             :                                                      len - offset,
     142             :                                                      NULL, &error);
     143           0 :                         break;
     144           0 :                 case FLOWSPEC_FRAGMENT:
     145             :                 case FLOWSPEC_TCP_FLAGS:
     146           0 :                         ret = bgp_flowspec_bitmask_decode(
     147             :                                                 BGP_FLOWSPEC_VALIDATE_ONLY,
     148             :                                                 nlri_content+offset,
     149             :                                                 len - offset,
     150             :                                                 NULL, &error);
     151           0 :                         break;
     152           0 :                 case FLOWSPEC_PKT_LEN:
     153             :                 case FLOWSPEC_DSCP:
     154           0 :                         ret = bgp_flowspec_op_decode(
     155             :                                                 BGP_FLOWSPEC_VALIDATE_ONLY,
     156             :                                                 nlri_content + offset,
     157             :                                                 len - offset, NULL,
     158             :                                                 &error);
     159           0 :                         break;
     160           0 :                 default:
     161           0 :                         error = -1;
     162           0 :                         break;
     163             :                 }
     164           0 :                 offset += ret;
     165             :         }
     166             :         return false;
     167             : }
     168             : 
     169             : /*
     170             :  * handle the flowspec address src/dst or generic address NLRI
     171             :  * return number of bytes analysed ( >= 0).
     172             :  */
     173           0 : int bgp_flowspec_ip_address(enum bgp_flowspec_util_nlri_t type,
     174             :                             uint8_t *nlri_ptr,
     175             :                             uint32_t max_len,
     176             :                             void *result, int *error,
     177             :                             afi_t afi,
     178             :                             uint8_t *ipv6_offset)
     179             : {
     180           0 :         char *display = (char *)result; /* for return_string */
     181           0 :         struct prefix *prefix = (struct prefix *)result;
     182           0 :         uint32_t offset = 0;
     183           0 :         struct prefix prefix_local;
     184           0 :         int psize;
     185           0 :         uint8_t prefix_offset = 0;
     186             : 
     187           0 :         *error = 0;
     188           0 :         memset(&prefix_local, 0, sizeof(prefix_local));
     189             :         /* read the prefix length */
     190           0 :         prefix_local.prefixlen = nlri_ptr[offset];
     191           0 :         psize = PSIZE(prefix_local.prefixlen);
     192           0 :         offset++;
     193           0 :         prefix_local.family = afi2family(afi);
     194           0 :         if (prefix_local.family == AF_INET6) {
     195           0 :                 prefix_offset = nlri_ptr[offset];
     196           0 :                 if (ipv6_offset)
     197           0 :                         *ipv6_offset = prefix_offset;
     198             :                 offset++;
     199             :         }
     200             :         /* Prefix length check. */
     201           0 :         if (prefix_local.prefixlen > prefix_blen(&prefix_local) * 8)
     202           0 :                 *error = -1;
     203             :         /* When packet overflow occur return immediately. */
     204           0 :         if (psize + offset > max_len)
     205           0 :                 *error = -1;
     206             :         /* Defensive coding, double-check
     207             :          * the psize fits in a struct prefix
     208             :          */
     209           0 :         if (psize > (ssize_t)sizeof(prefix_local.u))
     210             :                 *error = -1;
     211           0 :         memcpy(&prefix_local.u.prefix, &nlri_ptr[offset], psize);
     212           0 :         offset += psize;
     213           0 :         switch (type) {
     214           0 :         case BGP_FLOWSPEC_RETURN_STRING:
     215           0 :                 if (prefix_local.family == AF_INET6) {
     216           0 :                         int ret;
     217             : 
     218           0 :                         ret = snprintfrr(
     219             :                                 display, BGP_FLOWSPEC_STRING_DISPLAY_MAX,
     220             :                                 "%pFX/off %u", &prefix_local, prefix_offset);
     221           0 :                         if (ret < 0) {
     222           0 :                                 *error = -1;
     223           0 :                                 break;
     224             :                         }
     225             :                 } else
     226           0 :                         prefix2str(&prefix_local, display,
     227             :                                    BGP_FLOWSPEC_STRING_DISPLAY_MAX);
     228             :                 break;
     229           0 :         case BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE:
     230           0 :                 if (prefix)
     231           0 :                         prefix_copy(prefix, &prefix_local);
     232             :                 break;
     233             :         case BGP_FLOWSPEC_VALIDATE_ONLY:
     234             :         case BGP_FLOWSPEC_RETURN_JSON:
     235             :                 break;
     236             :         }
     237           0 :         return offset;
     238             : }
     239             : 
     240             : /*
     241             :  * handle the flowspec operator NLRI
     242             :  * return number of bytes analysed
     243             :  * if there is an error, the passed error param is used to give error:
     244             :  * -1 if decoding error,
     245             :  * if result is a string, its assumed length
     246             :  *  is BGP_FLOWSPEC_STRING_DISPLAY_MAX
     247             :  */
     248           0 : int bgp_flowspec_op_decode(enum bgp_flowspec_util_nlri_t type,
     249             :                            uint8_t *nlri_ptr,
     250             :                            uint32_t max_len,
     251             :                            void *result, int *error)
     252             : {
     253           0 :         int op[8];
     254           0 :         int len, value, value_size;
     255           0 :         int loop = 0;
     256           0 :         char *ptr = (char *)result; /* for return_string */
     257           0 :         uint32_t offset = 0;
     258           0 :         int len_string = BGP_FLOWSPEC_STRING_DISPLAY_MAX;
     259           0 :         int len_written;
     260           0 :         struct bgp_pbr_match_val *mval = (struct bgp_pbr_match_val *)result;
     261             : 
     262           0 :         *error = 0;
     263           0 :         do {
     264           0 :                 if (loop > BGP_PBR_MATCH_VAL_MAX)
     265           0 :                         *error = -2;
     266           0 :                 hex2bin(&nlri_ptr[offset], op);
     267           0 :                 offset++;
     268           0 :                 len = 2*op[2]+op[3];
     269           0 :                 value_size = 1 << len;
     270           0 :                 value = hexstr2num(&nlri_ptr[offset], value_size);
     271             :                 /* can not be < and > at the same time */
     272           0 :                 if (op[5] == 1 && op[6] == 1)
     273           0 :                         *error = -1;
     274             :                 /* if first element, AND bit can not be set */
     275           0 :                 if (op[1] == 1 && loop == 0)
     276           0 :                         *error = -1;
     277           0 :                 switch (type) {
     278           0 :                 case BGP_FLOWSPEC_RETURN_STRING:
     279           0 :                         if (loop) {
     280           0 :                                 len_written = snprintf(ptr, len_string,
     281             :                                                       ", ");
     282           0 :                                 len_string -= len_written;
     283           0 :                                 ptr += len_written;
     284             :                         }
     285           0 :                         if (op[5] == 1) {
     286           0 :                                 len_written = snprintf(ptr, len_string,
     287             :                                                        "<");
     288           0 :                                 len_string -= len_written;
     289           0 :                                 ptr += len_written;
     290             :                         }
     291           0 :                         if (op[6] == 1) {
     292           0 :                                 len_written = snprintf(ptr, len_string,
     293             :                                                       ">");
     294           0 :                                 len_string -= len_written;
     295           0 :                                 ptr += len_written;
     296             :                         }
     297           0 :                         if (op[7] == 1) {
     298           0 :                                 len_written = snprintf(ptr, len_string,
     299             :                                                        "=");
     300           0 :                                 len_string -= len_written;
     301           0 :                                 ptr += len_written;
     302             :                         }
     303           0 :                         len_written = snprintf(ptr, len_string,
     304             :                                                " %d ", value);
     305           0 :                         len_string -= len_written;
     306           0 :                         ptr += len_written;
     307           0 :                         break;
     308           0 :                 case BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE:
     309             :                         /* limitation: stop converting */
     310           0 :                         if (*error == -2)
     311             :                                 break;
     312           0 :                         mval->value = value;
     313           0 :                         if (op[5] == 1)
     314           0 :                                 mval->compare_operator |=
     315             :                                         OPERATOR_COMPARE_LESS_THAN;
     316           0 :                         if (op[6] == 1)
     317           0 :                                 mval->compare_operator |=
     318             :                                         OPERATOR_COMPARE_GREATER_THAN;
     319           0 :                         if (op[7] == 1)
     320           0 :                                 mval->compare_operator |=
     321             :                                         OPERATOR_COMPARE_EQUAL_TO;
     322           0 :                         if (op[1] == 1)
     323           0 :                                 mval->unary_operator = OPERATOR_UNARY_AND;
     324             :                         else
     325           0 :                                 mval->unary_operator = OPERATOR_UNARY_OR;
     326           0 :                         mval++;
     327           0 :                         break;
     328             :                 case BGP_FLOWSPEC_VALIDATE_ONLY:
     329             :                 case BGP_FLOWSPEC_RETURN_JSON:
     330             :                         /* no action */
     331             :                         break;
     332             :                 }
     333           0 :                 offset += value_size;
     334           0 :                 loop++;
     335           0 :         } while (op[0] == 0 && offset < max_len - 1);
     336           0 :         if (offset > max_len)
     337           0 :                 *error = -1;
     338             :         /* use error parameter to count the number of entries */
     339           0 :         if (*error == 0)
     340           0 :                 *error = loop;
     341           0 :         return offset;
     342             : }
     343             : 
     344             : 
     345             : /*
     346             :  * handle the flowspec tcpflags or fragment field
     347             :  * return number of bytes analysed
     348             :  * if there is an error, the passed error param is used to give error:
     349             :  * -1 if decoding error,
     350             :  * if result is a string, its assumed length
     351             :  *  is BGP_FLOWSPEC_STRING_DISPLAY_MAX
     352             :  */
     353           0 : int bgp_flowspec_bitmask_decode(enum bgp_flowspec_util_nlri_t type,
     354             :                                  uint8_t *nlri_ptr,
     355             :                                  uint32_t max_len,
     356             :                                  void *result, int *error)
     357             : {
     358           0 :         int op[8];
     359           0 :         int len, value_size, loop = 0, value;
     360           0 :         char *ptr = (char *)result; /* for return_string */
     361           0 :         struct bgp_pbr_match_val *mval = (struct bgp_pbr_match_val *)result;
     362           0 :         uint32_t offset = 0;
     363           0 :         int len_string = BGP_FLOWSPEC_STRING_DISPLAY_MAX;
     364           0 :         int len_written;
     365             : 
     366           0 :         *error = 0;
     367           0 :         do {
     368           0 :                 if (loop > BGP_PBR_MATCH_VAL_MAX)
     369           0 :                         *error = -2;
     370           0 :                 hex2bin(&nlri_ptr[offset], op);
     371             :                 /* if first element, AND bit can not be set */
     372           0 :                 if (op[1] == 1 && loop == 0)
     373           0 :                         *error = -1;
     374           0 :                 offset++;
     375           0 :                 len = 2 * op[2] + op[3];
     376           0 :                 value_size = 1 << len;
     377           0 :                 value = hexstr2num(&nlri_ptr[offset], value_size);
     378           0 :                 switch (type) {
     379           0 :                 case BGP_FLOWSPEC_RETURN_STRING:
     380           0 :                         if (op[1] == 1 && loop != 0) {
     381           0 :                                 len_written = snprintf(ptr, len_string,
     382             :                                                        ",&");
     383           0 :                                 len_string -= len_written;
     384           0 :                                 ptr += len_written;
     385           0 :                         } else if (op[1] == 0 && loop != 0) {
     386           0 :                                 len_written = snprintf(ptr, len_string,
     387             :                                                       ",|");
     388           0 :                                 len_string -= len_written;
     389           0 :                                 ptr += len_written;
     390             :                         }
     391           0 :                         if (op[7] == 1) {
     392           0 :                                 len_written = snprintf(ptr, len_string,
     393             :                                                "= ");
     394           0 :                                 len_string -= len_written;
     395           0 :                                 ptr += len_written;
     396             :                         } else {
     397           0 :                                 len_written = snprintf(ptr, len_string,
     398             :                                                        "∋ ");
     399           0 :                                 len_string -= len_written;
     400           0 :                                 ptr += len_written;
     401             :                         }
     402           0 :                         if (op[6] == 1) {
     403           0 :                                 len_written = snprintf(ptr, len_string,
     404             :                                                "! ");
     405           0 :                                 len_string -= len_written;
     406           0 :                                 ptr += len_written;
     407             :                         }
     408           0 :                         len_written = snprintf(ptr, len_string,
     409             :                                        "%d", value);
     410           0 :                         len_string -= len_written;
     411           0 :                         ptr += len_written;
     412           0 :                         break;
     413           0 :                 case BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE:
     414             :                         /* limitation: stop converting */
     415           0 :                         if (*error == -2)
     416             :                                 break;
     417           0 :                         mval->value = value;
     418           0 :                         if (op[6] == 1) {
     419             :                                 /* different from */
     420           0 :                                 mval->compare_operator |=
     421             :                                         OPERATOR_COMPARE_LESS_THAN;
     422           0 :                                 mval->compare_operator |=
     423             :                                         OPERATOR_COMPARE_GREATER_THAN;
     424             :                         } else
     425           0 :                                 mval->compare_operator |=
     426             :                                         OPERATOR_COMPARE_EQUAL_TO;
     427           0 :                         if (op[7] == 1)
     428           0 :                                 mval->compare_operator |=
     429             :                                         OPERATOR_COMPARE_EXACT_MATCH;
     430           0 :                         if (op[1] == 1)
     431           0 :                                 mval->unary_operator =
     432             :                                         OPERATOR_UNARY_AND;
     433             :                         else
     434           0 :                                 mval->unary_operator =
     435             :                                         OPERATOR_UNARY_OR;
     436           0 :                         mval++;
     437           0 :                         break;
     438             :                 case BGP_FLOWSPEC_VALIDATE_ONLY:
     439             :                 case BGP_FLOWSPEC_RETURN_JSON:
     440             :                         /* no action */
     441             :                         break;
     442             :                 }
     443           0 :                 offset += value_size;
     444           0 :                 loop++;
     445           0 :         } while (op[0] == 0 && offset < max_len - 1);
     446           0 :         if (offset > max_len)
     447           0 :                 *error = -1;
     448             :         /* use error parameter to count the number of entries */
     449           0 :         if (*error == 0)
     450           0 :                 *error = loop;
     451           0 :         return offset;
     452             : }
     453             : 
     454           0 : int bgp_flowspec_match_rules_fill(uint8_t *nlri_content, int len,
     455             :                                   struct bgp_pbr_entry_main *bpem,
     456             :                                   afi_t afi)
     457             : {
     458           0 :         int offset = 0, error = 0;
     459           0 :         struct prefix *prefix;
     460           0 :         struct bgp_pbr_match_val *mval;
     461           0 :         uint8_t *match_num;
     462           0 :         uint8_t bitmask = 0;
     463           0 :         int ret = 0, type;
     464           0 :         uint8_t *prefix_offset;
     465             : 
     466           0 :         while (offset < len - 1 && error >= 0) {
     467           0 :                 type = nlri_content[offset];
     468           0 :                 offset++;
     469           0 :                 switch (type) {
     470           0 :                 case FLOWSPEC_DEST_PREFIX:
     471             :                 case FLOWSPEC_SRC_PREFIX:
     472           0 :                         bitmask = 0;
     473           0 :                         if (type == FLOWSPEC_DEST_PREFIX) {
     474           0 :                                 bitmask |= PREFIX_DST_PRESENT;
     475           0 :                                 prefix = &bpem->dst_prefix;
     476           0 :                                 prefix_offset = &bpem->dst_prefix_offset;
     477             :                         } else {
     478           0 :                                 bitmask |= PREFIX_SRC_PRESENT;
     479           0 :                                 prefix = &bpem->src_prefix;
     480           0 :                                 prefix_offset = &bpem->src_prefix_offset;
     481             :                         }
     482           0 :                         ret = bgp_flowspec_ip_address(
     483             :                                         BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE,
     484             :                                         nlri_content + offset,
     485           0 :                                         len - offset,
     486             :                                         prefix, &error,
     487             :                                         afi, prefix_offset);
     488           0 :                         if (error < 0)
     489           0 :                                 flog_err(EC_BGP_FLOWSPEC_PACKET,
     490             :                                          "%s: flowspec_ip_address error %d",
     491             :                                          __func__, error);
     492             :                         else {
     493             :                                 /* if src or dst address is 0.0.0.0,
     494             :                                  * ignore that rule
     495             :                                  */
     496           0 :                                 if (prefix->family == AF_INET
     497           0 :                                     && prefix->u.prefix4.s_addr == INADDR_ANY)
     498           0 :                                         bpem->match_bitmask_iprule |= bitmask;
     499           0 :                                 else if (prefix->family == AF_INET6
     500           0 :                                          && !memcmp(&prefix->u.prefix6,
     501             :                                                     &in6addr_any,
     502             :                                                     sizeof(struct in6_addr)))
     503           0 :                                         bpem->match_bitmask_iprule |= bitmask;
     504             :                                 else
     505           0 :                                         bpem->match_bitmask |= bitmask;
     506             :                         }
     507           0 :                         offset += ret;
     508           0 :                         break;
     509           0 :                 case FLOWSPEC_FLOW_LABEL:
     510           0 :                         if (afi == AFI_IP) {
     511           0 :                                 error = -1;
     512           0 :                                 continue;
     513             :                         }
     514           0 :                         match_num = &(bpem->match_flowlabel_num);
     515           0 :                         mval = (struct bgp_pbr_match_val *)
     516             :                                 &(bpem->flow_label);
     517           0 :                         offset += bgp_flowspec_call_non_opaque_decode(
     518             :                                                         nlri_content + offset,
     519             :                                                         len - offset,
     520             :                                                         mval, match_num,
     521             :                                                         &error);
     522           0 :                         break;
     523           0 :                 case FLOWSPEC_IP_PROTOCOL:
     524           0 :                         match_num = &(bpem->match_protocol_num);
     525           0 :                         mval = (struct bgp_pbr_match_val *)
     526             :                                 &(bpem->protocol);
     527           0 :                         offset += bgp_flowspec_call_non_opaque_decode(
     528             :                                                         nlri_content + offset,
     529             :                                                         len - offset,
     530             :                                                         mval, match_num,
     531             :                                                         &error);
     532           0 :                         break;
     533           0 :                 case FLOWSPEC_PORT:
     534           0 :                         match_num = &(bpem->match_port_num);
     535           0 :                         mval = (struct bgp_pbr_match_val *)
     536             :                                 &(bpem->port);
     537           0 :                         offset += bgp_flowspec_call_non_opaque_decode(
     538             :                                                         nlri_content + offset,
     539             :                                                         len - offset,
     540             :                                                         mval, match_num,
     541             :                                                         &error);
     542           0 :                         break;
     543           0 :                 case FLOWSPEC_DEST_PORT:
     544           0 :                         match_num = &(bpem->match_dst_port_num);
     545           0 :                         mval = (struct bgp_pbr_match_val *)
     546             :                                 &(bpem->dst_port);
     547           0 :                         offset += bgp_flowspec_call_non_opaque_decode(
     548             :                                                         nlri_content + offset,
     549             :                                                         len - offset,
     550             :                                                         mval, match_num,
     551             :                                                         &error);
     552           0 :                         break;
     553           0 :                 case FLOWSPEC_SRC_PORT:
     554           0 :                         match_num = &(bpem->match_src_port_num);
     555           0 :                         mval = (struct bgp_pbr_match_val *)
     556             :                                 &(bpem->src_port);
     557           0 :                         offset += bgp_flowspec_call_non_opaque_decode(
     558             :                                                         nlri_content + offset,
     559             :                                                         len - offset,
     560             :                                                         mval, match_num,
     561             :                                                         &error);
     562           0 :                         break;
     563           0 :                 case FLOWSPEC_ICMP_TYPE:
     564           0 :                         match_num = &(bpem->match_icmp_type_num);
     565           0 :                         mval = (struct bgp_pbr_match_val *)
     566             :                                 &(bpem->icmp_type);
     567           0 :                         offset += bgp_flowspec_call_non_opaque_decode(
     568             :                                                         nlri_content + offset,
     569             :                                                         len - offset,
     570             :                                                         mval, match_num,
     571             :                                                         &error);
     572           0 :                         break;
     573           0 :                 case FLOWSPEC_ICMP_CODE:
     574           0 :                         match_num = &(bpem->match_icmp_code_num);
     575           0 :                         mval = (struct bgp_pbr_match_val *)
     576             :                                 &(bpem->icmp_code);
     577           0 :                         offset += bgp_flowspec_call_non_opaque_decode(
     578             :                                                         nlri_content + offset,
     579             :                                                         len - offset,
     580             :                                                         mval, match_num,
     581             :                                                         &error);
     582           0 :                         break;
     583           0 :                 case FLOWSPEC_PKT_LEN:
     584           0 :                         match_num =
     585             :                                 &(bpem->match_packet_length_num);
     586           0 :                         mval = (struct bgp_pbr_match_val *)
     587             :                                 &(bpem->packet_length);
     588           0 :                         offset += bgp_flowspec_call_non_opaque_decode(
     589             :                                                         nlri_content + offset,
     590             :                                                         len - offset,
     591             :                                                         mval, match_num,
     592             :                                                         &error);
     593           0 :                         break;
     594           0 :                 case FLOWSPEC_DSCP:
     595           0 :                         match_num = &(bpem->match_dscp_num);
     596           0 :                         mval = (struct bgp_pbr_match_val *)
     597             :                                 &(bpem->dscp);
     598           0 :                         offset += bgp_flowspec_call_non_opaque_decode(
     599             :                                                         nlri_content + offset,
     600             :                                                         len - offset,
     601             :                                                         mval, match_num,
     602             :                                                         &error);
     603           0 :                         break;
     604           0 :                 case FLOWSPEC_TCP_FLAGS:
     605           0 :                         ret = bgp_flowspec_bitmask_decode(
     606             :                                         BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE,
     607             :                                         nlri_content + offset,
     608           0 :                                         len - offset,
     609           0 :                                         &bpem->tcpflags, &error);
     610           0 :                         if (error < 0)
     611           0 :                                 flog_err(
     612             :                                         EC_BGP_FLOWSPEC_PACKET,
     613             :                                         "%s: flowspec_tcpflags_decode error %d",
     614             :                                         __func__, error);
     615             :                         else
     616           0 :                                 bpem->match_tcpflags_num = error;
     617             :                         /* contains the number of slots used */
     618           0 :                         offset += ret;
     619           0 :                         break;
     620           0 :                 case FLOWSPEC_FRAGMENT:
     621           0 :                         ret = bgp_flowspec_bitmask_decode(
     622             :                                         BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE,
     623             :                                         nlri_content + offset,
     624           0 :                                         len - offset, &bpem->fragment,
     625             :                                         &error);
     626           0 :                         if (error < 0)
     627           0 :                                 flog_err(
     628             :                                         EC_BGP_FLOWSPEC_PACKET,
     629             :                                         "%s: flowspec_fragment_type_decode error %d",
     630             :                                         __func__, error);
     631             :                         else
     632           0 :                                 bpem->match_fragment_num = error;
     633           0 :                         offset += ret;
     634           0 :                         break;
     635           0 :                 default:
     636           0 :                         flog_err(EC_LIB_DEVELOPMENT, "%s: unknown type %d",
     637             :                                  __func__, type);
     638             :                 }
     639             :         }
     640           0 :         if (bpem->match_packet_length_num || bpem->match_fragment_num
     641             :             || bpem->match_tcpflags_num || bpem->match_dscp_num
     642           0 :             || bpem->match_icmp_code_num || bpem->match_icmp_type_num
     643           0 :             || bpem->match_port_num || bpem->match_src_port_num
     644           0 :             || bpem->match_dst_port_num || bpem->match_protocol_num
     645           0 :             || bpem->match_bitmask || bpem->match_flowlabel_num)
     646           0 :                 bpem->type = BGP_PBR_IPSET;
     647           0 :         else if ((bpem->match_bitmask_iprule & PREFIX_SRC_PRESENT) ||
     648             :                  (bpem->match_bitmask_iprule & PREFIX_DST_PRESENT))
     649             :                 /* the extracted policy rule may not need an
     650             :                  * iptables/ipset filtering. check this may not be
     651             :                  * a standard ip rule : permit any to any ( eg)
     652             :                  */
     653           0 :                 bpem->type = BGP_PBR_IPRULE;
     654             :         else
     655           0 :                 bpem->type = BGP_PBR_UNDEFINED;
     656           0 :         return error;
     657             : }
     658             : 
     659             : /* return 1 if FS entry invalid or no NH IP */
     660           0 : bool bgp_flowspec_get_first_nh(struct bgp *bgp, struct bgp_path_info *pi,
     661             :                                struct prefix *p, afi_t afi)
     662             : {
     663           0 :         struct bgp_pbr_entry_main api;
     664           0 :         int i;
     665           0 :         struct bgp_dest *dest = pi->net;
     666           0 :         struct bgp_pbr_entry_action *api_action;
     667             : 
     668           0 :         memset(&api, 0, sizeof(api));
     669           0 :         if (bgp_pbr_build_and_validate_entry(bgp_dest_get_prefix(dest), pi,
     670             :                                              &api)
     671             :             < 0)
     672             :                 return true;
     673           0 :         for (i = 0; i < api.action_num; i++) {
     674           0 :                 api_action = &api.actions[i];
     675           0 :                 if (api_action->action != ACTION_REDIRECT_IP)
     676           0 :                         continue;
     677           0 :                 p->family = afi2family(afi);
     678           0 :                 if (afi == AFI_IP) {
     679           0 :                         p->prefixlen = IPV4_MAX_BITLEN;
     680           0 :                         p->u.prefix4 = api_action->u.zr.redirect_ip_v4;
     681             :                 } else {
     682           0 :                         p->prefixlen = IPV6_MAX_BITLEN;
     683           0 :                         memcpy(&p->u.prefix6, &api_action->u.zr.redirect_ip_v6,
     684             :                                sizeof(struct in6_addr));
     685             :                 }
     686             :                 return false;
     687             :         }
     688             :         return true;
     689             : }

Generated by: LCOV version v1.16-topotato