bfrt_helper.match
Base Match Type
Masked
- class Masked[source]
Bases:
object
Base class for all matches which can be represented in terms of a value and a mask.
- subset_of(other: Masked) bool [source]
Compares whether
self
is a subset ofother
.If all the elements in
self
are also inother
, then this object is a subset. This isTrue
even if both objects contain exactly the same elements.This is broadly equivalent to a
<=
(less than or equal to) operation, and is called by theMasked.__le__()
special method.See also:
Masked.proper_subset_of()
- Parameters:
other (Masked) – Other masked value to compare against.
- Returns:
True if
self
is subset ofother
- Return type:
bool
- superset_of(other: Masked) bool [source]
Compares whether
other
is a subset ofself
.If all the elements in
other
are also inself
, then this object is a superset. This isTrue
even if both objects contain exactly the same elements.This is broadly equivalent to a
>=
(less than or equal to) operation, and is called by theMasked.__ge__()
special method.See also:
Masked.proper_superset_of()
- Parameters:
other (Masked) – Other masked value to compare against.
- Returns:
True if
self
is superset ofother
- Return type:
bool
- proper_subset_of(other: Masked) bool [source]
Compares with another match, where
self
is found to be a proper subset of the other.If all the elements in
self
are present inother
, and,other
contains at least one element not inself
, then this object can be considered a proper subset.This is broadly equivalent to a
<
(less than) operation, and is called by theMasked.__lt__()
special method.See also:
Masked.subset_of()
- Parameters:
other (Masked) – Other masked value to compare against.
- Returns:
True if
self
is proper superset ofother
- Return type:
bool
- proper_superset_of(other: Masked) bool [source]
Compares with another match, where
self
is found to be a proper superset of the other.If all the elements in
other
are present inself
, and,self
contains at least one element not inother
, then this object can be considered a proper superset.This is broadly equivalent to a
>
(less than) operation, and is called by theMasked.__gt__()
special method.See also:
Masked.uperset_of()
- Parameters:
other (Masked) – Other masked value to compare against.
- Returns:
True if
self
is proper superset ofother
- Return type:
bool
- intersection(other: Masked) Masked [source]
Returns the intersection of
self
andother
.The intersection of two masked values is the common potential values between
self
andother
.The following relations should hold true, noting the use of proper subset and superset comparisons:
intersection = a & b assert a > intersection # Intersection is subset of a assert b > intersection # Intersection also subset of b
Since the intersection is the common elements, and if both a and b are proper supersets of the intersection, they must contain different/unique values.
- Returns:
Contains the elements which are common to
self
andother
.- Return type:
- merged(other: Masked) Masked [source]
Derives a
Masked
object whose mask has all “don’t care” bits from bothself
andother
.Note
This is not a union. As an example, a ternary expression \(A = 0101xxxx\) contains all possible values beginning with \(0101\). Another value \(B = xxxx0101\) contains all the possible values ending in \(0101\). A merge between the two yields the ternary expression \(I = xxxxxxxx\), where another value \(C = 11001100\) is subset to \(I\) but is in neither \(A\) or \(B\). If it were a union, any value that is subset must be in either \(A\) or :math`B`.
- Returns:
Contains values derived from
- Return type:
- overlaps(other: Masked) bool [source]
Returns whether or not two
Masked
matches overlap.Overlapping ternary expressions are defined where some, but not all, elements in a ternary \(A\) exist in a ternary \(B\), and, some, but not all, elements in \(B\) exist in \(A\). That is to say that they are neither proper superset or subset of each other, but they share elements.
If only one of these conditions held true, they would either be a proper subset or superset of one another. A corollary to this is that longest prefix matches do not overlap, they are strictly a subset or superset of one another.
That is to say that \(A\), being a proper superset of the intersection \(I\), has at least one element not in \(I\), and, \(B\), being a proper superset of \(I\), has at least one element not in intersection \(I\), implying that the elements contained in the differences between either \(A\) or \(B\) and the intersection are unique to each other.
- __le__(other: Masked) bool [source]
See
subset_of()
- __ge__(other: Masked) bool [source]
See
superset_of()
- __eq__(other: Masked) bool [source]
Equality compares two ternary expressions.
If both value and mask are the same between the two objects, then
True
is returned.
- __and__(other: Masked) Masked [source]
Returns the intersection of
self
andother
.see
intersection()
- __or__(other: Masked) Masked [source]
Returns a ternary with a merged mask of
self
andother
.see
merged()
- __iter__() iterator [source]
Creates an iterator that returns consecutive elements in the set of
Masked
, starting from the current value.The iterator itself is not efficient, it’s internal value is incremented until it finds a match on every iteration.
When the iterator is dereferenced, it returns either an LPM or Ternary expression, depending on what the derived class is.
Examples
Using a
PortID
:>>> match = Ternary(PortId(0x0), mask=0xc) >>> [str(x) for x in iter(match)] [ '0x0 &&& 0xf3', '0x4 &&& 0xf3', '0x8 &&& 0xf3', '0xc &&& 0xf3' ]
Or an
IPv4Address
:>>> match = Ternary(IPv4Address("192.168.42.24"), .. mask="255.255.255.252") >>> [str()] [ '192.168.42.24 &&& 255.255.255.252', '192.168.42.25 &&& 255.255.255.252', '192.168.42.26 &&& 255.255.255.252', '192.168.42.27 &&& 255.255.255.252', ]
- Returns:
An iterator object that
Supported Types
Exact
LongestPrefixMatch
Ternary
- class Ternary(value: Field, mask: Field | None = None, dont_care=False)[source]
Bases:
Masked
Matches values on specific bits.
A
Ternary
match is a match type which matches on specific bits of the value. This is achieved by the use of a mask; when a match is performed, both the the expected value and the compared value are ANDed with the mask, and an equality operation can be performed without comparing every single bit.Ternary
values are associated with TCAM () memory; and are stored in hardware as trits. These are like bits but have 3 states, on, off, and “don’t care”.Note
Masks could be represented by either
0
or1
for a match. In this case,1
bits represent bit’s which are matched against.This class represents a ternary expression as a combination of an integer value and a mask. This is because:
Python supports arbitrary length integers;
It is easier to perform bitwise operations on integers.
- Parameters:
The semantics of this match can change depending on whether a mask or
dont_care
is specified. By default, creating aTernary
match without amask
will match on every single bit, effectively acting in the same way asbfrt_helper.match.Exact
.The mask value does not have to be specified explictly as the same type as the value, any value will be accepted so long as it would be accepted by the value types constructor.
If
dont_care
is specified, no bits will be compared (i.e, the mask will contain all zeroes). This means that it will match on any value it’s compared against. This can be useful if a table specifies multiple key fields, and you wanted to match on another field, but not this specificTernary
element.Examples
A match on a
PortId
which only considers the 4 least significant bits:my_field = Ternary(PortId(42), PortId(0xf))
A match on a
PortId
which only considers the 4 least significant bits, but not specifying the mask in terms of the original type:my_field = Ternary(PortId(42), 0xf)
A match that will match exactly on a
PortId
of 42:my_field = Ternary(PortId(42))
A match that will match on any other
PortId
:my_field = Ternary(PortId(42), dont_care=True)
- value_bytes()[source]
Returns the match value as bytes.
- Returns:
Internal value converted into bytes.
- Return type:
bytes