Subject: Re: [Idr] The Use of 'm' and 'not' bits in bitmask Flowspec component.

From: PVLR Pavana Murthy <[email-masked]>
Date: Wed, 21 Feb 2018 12:22:00 +0530

Hi Christoph,
   The following is given in the RFC.

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| e | a |   len | 0 | 0 |not| m |
+---+---+---+---+---+---+---+---+

not - NOT bit. If set, logical negation of operation.

m - Match bit. If set, this is a bitwise match operation
defined as "(data & value) == value"; if unset, (data &
value) evaluates to TRUE if any of the bits in the value
mask are set in the data.

I will try to use all the combinations of 'not' and 'm' bits. Please let me
know if the following my understanding is correct.

I will try to use the mask with SYN, ACK bits of TCP header for this.
[CWR ECE URG ACK PSH RST SYN FIN]
mask = 0x12

   1. not-0, m-0  (data & mask) != 0 i.e. either SYN or ACK bits should
   have been set in TCP header.
   2. not-0, m-1  (data & mask)  == mask i.e. SYN and ACK bits both should
   be set in TCP header.
   3. not-1,m-0   (data & mask) == 0    i.e. both SYN and  ACK bits should
   not  be set in TCP header.
   4. not-1, m-1  (data & mask) != mask i.e. at least one of  SYN or ACK
   bits should not be set in TCP header.

Thanks,
Pavana.

On Thu, Feb 15, 2018 at 2:35 PM, PVLR Pavana Murthy <[email-masked]>
wrote:

> Hi Christoph,
>    Thanks a lot for the detailed explanation. That answers my question
> completely :-).
>
>
>
> On Thu, Feb 15, 2018 at 1:07 PM, Christoph Loibl <[email-masked]> wrote:
>
>> 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 :
>>
>> *) 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
>> [email-masked] | CL8-RIPE | PGP-Key-ID: 0x4B2C0055 | http://www.nextlayer.at
>>
>>
>>
>> On 15.02.2018, at 05:08, PVLR Pavana Murthy <[email-masked]> 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 <[email-masked]> 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
>>>
>>> Christoph
>>>
>>> --
>>> Christoph Loibl
>>> [email-masked] | CL8-RIPE | PGP-Key-ID: 0x4B2C0055 | http://www.nextlayer.at
>>>
>>>
>>>
>>> On 12.02.2018, at 12:03, PVLR Pavana Murthy <[email-masked]> 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
>>> [email-masked]
>>> https://www.ietf.org/mailman/listinfo/idr
>>>
>>>
>>>
>>
>>
>