back to topotato report
topotato coverage report
Current view: top level - bgpd - bgp_flowspec.c (source / functions) Hit Total Coverage
Test: test_bgp_set_aspath_replace.py::BGPSetAspathReplace Lines: 0 84 0.0 %
Date: 2023-02-24 18:37:49 Functions: 0 2 0.0 %

          Line data    Source code
       1             : /* BGP FlowSpec for packet handling
       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             : #include <math.h>
      23             : 
      24             : #include "prefix.h"
      25             : #include "lib_errors.h"
      26             : 
      27             : #include "bgpd/bgpd.h"
      28             : #include "bgpd/bgp_route.h"
      29             : #include "bgpd/bgp_flowspec.h"
      30             : #include "bgpd/bgp_flowspec_util.h"
      31             : #include "bgpd/bgp_flowspec_private.h"
      32             : #include "bgpd/bgp_ecommunity.h"
      33             : #include "bgpd/bgp_debug.h"
      34             : #include "bgpd/bgp_errors.h"
      35             : 
      36           0 : static int bgp_fs_nlri_validate(uint8_t *nlri_content, uint32_t len,
      37             :                                 afi_t afi)
      38             : {
      39           0 :         uint32_t offset = 0;
      40           0 :         int type;
      41           0 :         int ret = 0, error = 0;
      42             : 
      43           0 :         while (offset < len-1) {
      44           0 :                 type = nlri_content[offset];
      45           0 :                 offset++;
      46           0 :                 switch (type) {
      47           0 :                 case FLOWSPEC_DEST_PREFIX:
      48             :                 case FLOWSPEC_SRC_PREFIX:
      49           0 :                         ret = bgp_flowspec_ip_address(
      50             :                                                 BGP_FLOWSPEC_VALIDATE_ONLY,
      51             :                                                 nlri_content + offset,
      52             :                                                 len - offset, NULL, &error,
      53             :                                                 afi, NULL);
      54           0 :                         break;
      55           0 :                 case FLOWSPEC_FLOW_LABEL:
      56           0 :                         if (afi == AFI_IP)
      57             :                                 return -1;
      58           0 :                         ret = bgp_flowspec_op_decode(BGP_FLOWSPEC_VALIDATE_ONLY,
      59             :                                                    nlri_content + offset,
      60             :                                                    len - offset, NULL, &error);
      61           0 :                         break;
      62           0 :                 case FLOWSPEC_IP_PROTOCOL:
      63             :                 case FLOWSPEC_PORT:
      64             :                 case FLOWSPEC_DEST_PORT:
      65             :                 case FLOWSPEC_SRC_PORT:
      66             :                 case FLOWSPEC_ICMP_TYPE:
      67             :                 case FLOWSPEC_ICMP_CODE:
      68           0 :                         ret = bgp_flowspec_op_decode(BGP_FLOWSPEC_VALIDATE_ONLY,
      69             :                                                    nlri_content + offset,
      70             :                                                    len - offset, NULL, &error);
      71           0 :                         break;
      72           0 :                 case FLOWSPEC_TCP_FLAGS:
      73             :                 case FLOWSPEC_FRAGMENT:
      74           0 :                         ret = bgp_flowspec_bitmask_decode(
      75             :                                                    BGP_FLOWSPEC_VALIDATE_ONLY,
      76             :                                                    nlri_content + offset,
      77             :                                                    len - offset, NULL, &error);
      78           0 :                         break;
      79           0 :                 case FLOWSPEC_PKT_LEN:
      80             :                 case FLOWSPEC_DSCP:
      81           0 :                         ret = bgp_flowspec_op_decode(
      82             :                                                 BGP_FLOWSPEC_VALIDATE_ONLY,
      83             :                                                 nlri_content + offset,
      84             :                                                 len - offset, NULL, &error);
      85           0 :                         break;
      86           0 :                 default:
      87           0 :                         error = -1;
      88           0 :                         break;
      89             :                 }
      90           0 :                 offset += ret;
      91           0 :                 if (error < 0)
      92             :                         break;
      93             :         }
      94           0 :         return error;
      95             : }
      96             : 
      97           0 : int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
      98             :                             struct bgp_nlri *packet, int withdraw)
      99             : {
     100           0 :         uint8_t *pnt;
     101           0 :         uint8_t *lim;
     102           0 :         afi_t afi;
     103           0 :         safi_t safi;
     104           0 :         int psize = 0;
     105           0 :         struct prefix p;
     106           0 :         void *temp;
     107             : 
     108             :         /* Start processing the NLRI - there may be multiple in the MP_REACH */
     109           0 :         pnt = packet->nlri;
     110           0 :         lim = pnt + packet->length;
     111           0 :         afi = packet->afi;
     112           0 :         safi = packet->safi;
     113             : 
     114           0 :         if (packet->length >= FLOWSPEC_NLRI_SIZELIMIT_EXTENDED) {
     115           0 :                 flog_err(EC_BGP_FLOWSPEC_PACKET,
     116             :                          "BGP flowspec nlri length maximum reached (%u)",
     117             :                          packet->length);
     118           0 :                 return BGP_NLRI_PARSE_ERROR_FLOWSPEC_NLRI_SIZELIMIT;
     119             :         }
     120             : 
     121           0 :         for (; pnt < lim; pnt += psize) {
     122             :                 /* Clear prefix structure. */
     123           0 :                 memset(&p, 0, sizeof(p));
     124             : 
     125             :                 /* All FlowSpec NLRI begin with length. */
     126           0 :                 if (pnt + 1 > lim)
     127             :                         return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
     128             : 
     129           0 :                 psize = *pnt++;
     130           0 :                 if (psize >= FLOWSPEC_NLRI_SIZELIMIT) {
     131           0 :                         psize &= 0x0f;
     132           0 :                         psize = psize << 8;
     133           0 :                         psize |= *pnt++;
     134             :                 }
     135             :                 /* When packet overflow occur return immediately. */
     136           0 :                 if (pnt + psize > lim) {
     137           0 :                         flog_err(
     138             :                                 EC_BGP_FLOWSPEC_PACKET,
     139             :                                 "Flowspec NLRI length inconsistent ( size %u seen)",
     140             :                                 psize);
     141           0 :                         return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
     142             :                 }
     143           0 :                 if (bgp_fs_nlri_validate(pnt, psize, afi) < 0) {
     144           0 :                         flog_err(
     145             :                                 EC_BGP_FLOWSPEC_PACKET,
     146             :                                 "Bad flowspec format or NLRI options not supported");
     147           0 :                         return BGP_NLRI_PARSE_ERROR_FLOWSPEC_BAD_FORMAT;
     148             :                 }
     149           0 :                 p.family = AF_FLOWSPEC;
     150           0 :                 p.prefixlen = 0;
     151             :                 /* Flowspec encoding is in bytes */
     152           0 :                 p.u.prefix_flowspec.prefixlen = psize;
     153           0 :                 p.u.prefix_flowspec.family = afi2family(afi);
     154           0 :                 temp = XCALLOC(MTYPE_TMP, psize);
     155           0 :                 memcpy(temp, pnt, psize);
     156           0 :                 p.u.prefix_flowspec.ptr = (uintptr_t) temp;
     157             : 
     158           0 :                 if (BGP_DEBUG(flowspec, FLOWSPEC)) {
     159           0 :                         char return_string[BGP_FLOWSPEC_NLRI_STRING_MAX];
     160           0 :                         char local_string[BGP_FLOWSPEC_NLRI_STRING_MAX*2+16];
     161           0 :                         char ec_string[BGP_FLOWSPEC_NLRI_STRING_MAX];
     162           0 :                         char *s = NULL;
     163             : 
     164           0 :                         bgp_fs_nlri_get_string((unsigned char *)
     165             :                                                p.u.prefix_flowspec.ptr,
     166           0 :                                                p.u.prefix_flowspec.prefixlen,
     167             :                                                return_string,
     168             :                                                NLRI_STRING_FORMAT_MIN, NULL,
     169             :                                                afi);
     170           0 :                         snprintf(ec_string, sizeof(ec_string),
     171             :                                  "EC{none}");
     172           0 :                         if (attr && bgp_attr_get_ecommunity(attr)) {
     173           0 :                                 s = ecommunity_ecom2str(
     174             :                                         bgp_attr_get_ecommunity(attr),
     175             :                                         ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
     176           0 :                                 snprintf(ec_string, sizeof(ec_string),
     177             :                                          "EC{%s}",
     178             :                                         s == NULL ? "none" : s);
     179             : 
     180           0 :                                 if (s)
     181           0 :                                         ecommunity_strfree(&s);
     182             :                         }
     183           0 :                         snprintf(local_string, sizeof(local_string),
     184             :                                  "FS Rx %s %s %s %s", withdraw ?
     185             :                                  "Withdraw":"Update",
     186             :                                  afi2str(afi), return_string,
     187             :                                  attr != NULL ? ec_string : "");
     188           0 :                         zlog_info("%s", local_string);
     189             :                 }
     190             :                 /* Process the route. */
     191           0 :                 if (!withdraw)
     192           0 :                         bgp_update(peer, &p, 0, attr, afi, safi,
     193             :                                    ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
     194             :                                    NULL, 0, 0, NULL);
     195             :                 else
     196           0 :                         bgp_withdraw(peer, &p, 0, attr, afi, safi,
     197             :                                      ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
     198             :                                      NULL, 0, NULL);
     199             :         }
     200             :         return BGP_NLRI_PARSE_OK;
     201             : }

Generated by: LCOV version v1.16-topotato