Re: [Idr] BGP Flowspec rules precedence order (RFC 5575)

Christoph Loibl <c@tix.at> Thu, 15 February 2018 07:38 UTC

Return-Path: <c@tix.at>
X-Original-To: idr@ietfa.amsl.com
Delivered-To: idr@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id EA639124BAC for <idr@ietfa.amsl.com>; Wed, 14 Feb 2018 23:38:00 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.897
X-Spam-Level:
X-Spam-Status: No, score=-1.897 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, HTML_MESSAGE=0.001, NORMAL_HTTP_TO_IP=0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ANOKeSFSxh5U for <idr@ietfa.amsl.com>; Wed, 14 Feb 2018 23:37:57 -0800 (PST)
Received: from mail.hated.at (mail.hated.at [IPv6:2001:858:2:8::235]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 353BB126C23 for <idr@ietf.org>; Wed, 14 Feb 2018 23:37:56 -0800 (PST)
Received: from 80-110-127-16.cgn.dynamic.surfer.at ([80.110.127.16] helo=[192.168.66.220]) by mail.hated.at with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from <c@tix.at>) id 1emDoY-0004w3-Bz; Thu, 15 Feb 2018 08:18:43 +0100
From: Christoph Loibl <c@tix.at>
Message-Id: <9A8127C2-BADC-4E09-BE54-EBB5D07C994B@tix.at>
Content-Type: multipart/signed; boundary="Apple-Mail=_D56CC54C-4684-4A40-A77C-92151ED364AB"; protocol="application/pgp-signature"; micalg="pgp-sha1"
Mime-Version: 1.0 (Mac OS X Mail 11.2 \(3445.5.20\))
Date: Thu, 15 Feb 2018 08:37:51 +0100
In-Reply-To: <CAN-MQG59aTOKYVULVscfK_Mx3L8xcaXhny=1q4E5yi2+7rc2kQ@mail.gmail.com>
Cc: idr wg <idr@ietf.org>
To: PVLR Pavana Murthy <pvlrpm@gmail.com>
References: <CAN-MQG6xnsP28Xn3d7-PECkJrDSk-+QuKZawmAgJs6c-j536=w@mail.gmail.com> <372B554B-47F1-49AC-8D66-37A7ED69E57F@tix.at> <CAN-MQG59aTOKYVULVscfK_Mx3L8xcaXhny=1q4E5yi2+7rc2kQ@mail.gmail.com>
X-Mailer: Apple Mail (2.3445.5.20)
Archived-At: <https://mailarchive.ietf.org/arch/msg/idr/jhqPHfibzl5nu85eDvkUyJRfE-4>
Subject: Re: [Idr] BGP Flowspec rules precedence order (RFC 5575)
X-BeenThere: idr@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: Inter-Domain Routing <idr.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/idr>, <mailto:idr-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/idr/>
List-Post: <mailto:idr@ietf.org>
List-Help: <mailto:idr-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/idr>, <mailto:idr-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 15 Feb 2018 07:38:01 -0000

Hi Pavana,

You can rather easily test the behaviour when you feed your case into the python function:

def main():
    fs1 = FS_nlri(components=[
        FS_component(component_type=IP_DESTINATION, value=ipaddress.ip_network('88.88.88.0/24')),
        FS_component(component_type=4, value=bytearray([0x01, 0x46, 0x81, 0x50]))
    ])

    fs2 = FS_nlri(components=[
        FS_component(component_type=IP_DESTINATION, value=ipaddress.ip_network('88.88.88.0/24')),
        FS_component(component_type=4, value=bytearray([0x03, 0x5a, 0xc5, 0x6e]))
    ])
    print(flow_rule_cmp(fs1, fs2))

What happens is (I refer to line numbers of the code in the github repo
https://github.com/stoffi92/flowspec-cmp/blob/master/flow_cmp.py <https://github.com/stoffi92/flowspec-cmp/blob/master/flow_cmp.py> :

*) The IP components are compared and as you mentioned: no decision can be made since the ip components are equal. (we reach line 74 for the equal ip components and continue with the next iteration)

*) The second component _types_ are equal but not IP (we end up in the branch in line 80 since the components are type=4 and not 1 or 2)

*) The length of the second components is compared and equal, so we continue in line 82

** See below: this is basically where the compare that you asked for happens **

*) Now we come to the point where we compare the string of bytes one by one. As long as they are equal. (this is basically what memcmp does - this is not very explicit in the python code, since it is done by the <, > operators for the bytearray implicitly)

In your case what it does is, that it compares 0x01 to 0x03 and figures out that 0x01 is the lower value so it takes the branch in line 84 and returns with A_HAS_PRECEDENCE from line 85 (if both of your components would start with 0x01 it would continue to the second byte and so on).

Your first FS nlri has precedence because of the “lower” value.

>> 01 18 58 58 58 04 01 46 81 50  ----> Dst.Prefix: 88.88.88.0/24 <http://88.88.88.0/24>  Port: 70 | 80

Discamer: I assumed that you encoded the components themselfs correctly (the 01 46 81 50 and 03 5a c5 6e)

Does this answer your question?

Christoph

--
Christoph Loibl
c@tix.at | CL8-RIPE | PGP-Key-ID: 0x4B2C0055 | http://www.nextlayer.at



> On 15.02.2018, at 05:08, PVLR Pavana Murthy <pvlrpm@gmail.com> wrote:
> 
> Hi Christoph,
>   Even in the  RFC5575bis,  the following is given  for comparing non-prefix type components.
> 
>  else:
>                # assuming comp_a.value, comp_b.value of type bytearray
>                if len(comp_a.value) == len(comp_b.value):
>                    if comp_a.value > comp_b.value:
>                        return B_HAS_PRECEDENCE
>                    if comp_a.value < comp_b.value:
>                        return A_HAS_PRECEDENCE
>                    # components equal -> continue with next component
>                else:
>                    common = min(len(comp_a.value), len(comp_b.value))
>                    if comp_a.value[:common] > comp_b.value[:common]:
>                        return B_HAS_PRECEDENCE
>                    elif comp_a.value[:common] < comp_b.value[:common]:
>                        return A_HAS_PRECEDENCE
>                    # the first common bytes match
>                    elif len(comp_a.value) > len(comp_b.value):
>                        return A_HAS_PRECEDENCE
>                    else:
>                        return B_HAS_PRECEDENCE
> 
> What is  comp_a.value here ? Is it the binary sting of [op, value]/[op,bitmask] or only value/bitmask ?
> 
> Thanks,
> Pavana.
> 
> On Thu, Feb 15, 2018 at 3:11 AM, Christoph Loibl <c@tix.at <mailto:c@tix.at>> wrote:
> Hi Pavana,
> 
> Did you have a look into the actual code (thanks to Job’s comment) that is contained in the RFC5575bis draft which should be identical from the behaviour:
> 
> https://tools.ietf.org/html/draft-ietf-idr-rfc5575bis-06 <https://tools.ietf.org/html/draft-ietf-idr-rfc5575bis-06>
> 
> Christoph
> 
> --
> Christoph Loibl
> c@tix.at <mailto:c@tix.at> | CL8-RIPE | PGP-Key-ID: 0x4B2C0055 | http://www.nextlayer.at <http://www.nextlayer.at/>
> 
> 
> 
>> On 12.02.2018, at 12:03, PVLR Pavana Murthy <pvlrpm@gmail.com <mailto:pvlrpm@gmail.com>> wrote:
>> 
>> Hello,
>>   In the RFC 5575, the following is given for the comparing the Flowspec components of types other then prefix.
>> 
>> } else {
>> common =
>> MIN(component_length(comp1), component_length(comp2));
>> cmp = memcmp(data(comp1), data(comp2), common);
>> // not equal, lowest value has precedence
>> // equal, longest string has precedence
>> }
>> 
>> 
>> Here, what does data refrer to  ?
>> 
>> Is it the binary form of 1) [op, value]> / [op, bitmask]  or 2) Just [value] / [bitmask]
>> 
>> eg:
>> 
>> 
>> 1)  01 18 58 58 58 04 01 46 81 50  ----> Dst.Prefix: 88.88.88.0/24 <http://88.88.88.0/24>  Port: 70 | 80
>> 
>> 2)  01 18 58 58 58 04 03 5a c5 6e    ---->   Dst.Prefix: 88.88.88.0/24 <http://88.88.88.0/24>  Port: >=90 & <= 110
>> 
>> In the above FS rules,  Dst. Prefix is same in both, so we need to compare the data of next type 4 (Port).
>> So do we need to do memcmp of  (01 46 81 50) and  (03 5a c5 6e) ?
>> 
>> Thanks,
>> Pavana.
>> 
>> 
>> 
>> _______________________________________________
>> Idr mailing list
>> Idr@ietf.org <mailto:Idr@ietf.org>
>> https://www.ietf.org/mailman/listinfo/idr <https://www.ietf.org/mailman/listinfo/idr>
> 
>