Order VRFs by route distinguisher (RD) #785

Closed
opened 2025-12-29 16:25:47 +01:00 by adam · 9 comments
Owner

Originally created by @InsaneSplash on GitHub (Mar 22, 2017).

Would it be possible to look at sorting the RD column within the VRF list numerically. Currently is sorting it from first to last, rather than its numerical value.

Current:

1
100
1000
2
200
2000

Preferred:

1
2
100
200
1000
2000
Originally created by @InsaneSplash on GitHub (Mar 22, 2017). Would it be possible to look at sorting the RD column within the VRF list numerically. Currently is sorting it from first to last, rather than its numerical value. **Current:** ``` 1 100 1000 2 200 2000 ``` **Preferred:** ``` 1 2 100 200 1000 2000 ```
adam added the type: feature label 2025-12-29 16:25:47 +01:00
adam closed this issue 2025-12-29 16:25:47 +01:00
Author
Owner

@jeremystretch commented on GitHub (Mar 22, 2017):

This might be difficult to achieve, since the RD can take several forms (and we don't do any validation on it). RFC4364 allows for the following encodings:

  • <16-bit ASN>:<32-bit number>
  • <32-bit IP>:<16-bit number>
  • <32-bit ASN>:<16-bit number>

I'm not sure how we'd go about sorting those.

Edit: We could split on a : and try CASTing the two parts as integers, then sorting by those parts before the whole field. This completely ignores the second case though.

@jeremystretch commented on GitHub (Mar 22, 2017): This might be difficult to achieve, since the RD can take several forms (and we don't do any validation on it). [RFC4364](https://tools.ietf.org/html/rfc4364#page-14) allows for the following encodings: * <16-bit ASN>:<32-bit number> * <32-bit IP>:<16-bit number> * <32-bit ASN>:<16-bit number> I'm not sure how we'd go about sorting those. Edit: We _could_ split on a `:` and try CASTing the two parts as integers, then sorting by those parts before the whole field. This completely ignores the second case though.
Author
Owner

@ktims commented on GitHub (Mar 22, 2017):

I suppose the easiest way to accomplish numeric sorting for all 3 types would be to cast the RD to its full 6-byte integer value (type is not typically included in the representation) and sort by that.

Something like this perhaps? Should probably also check that the integers are in range, then it could be used for validation also.

def rd_to_int(rd):
  parts = rd.split(':')
  if len(parts) != 2:
    raise ValueError("Invalid format for RD, see RFC 4364")
  try:
    parts = [int(p) for p in parts]
    if parts[0] < 65536: # type 0
      return (parts[0] << 32) | parts[1]
    else: # type 2
      return (parts[0] << 16) | parts[1]
  except ValueError: # type 1
    return (int(IPAddress(parts[0])) << 16) | int(parts[1])
@ktims commented on GitHub (Mar 22, 2017): I suppose the easiest way to accomplish numeric sorting for all 3 types would be to cast the RD to its full 6-byte integer value (type is not typically included in the representation) and sort by that. Something like this perhaps? Should probably also check that the integers are in range, then it could be used for validation also. ```python def rd_to_int(rd): parts = rd.split(':') if len(parts) != 2: raise ValueError("Invalid format for RD, see RFC 4364") try: parts = [int(p) for p in parts] if parts[0] < 65536: # type 0 return (parts[0] << 32) | parts[1] else: # type 2 return (parts[0] << 16) | parts[1] except ValueError: # type 1 return (int(IPAddress(parts[0])) << 16) | int(parts[1]) ```
Author
Owner

@jeremystretch commented on GitHub (Mar 22, 2017):

@ktims The evaluation needs to be done in SQL though. Otherwise, we'd have to dump the entire table to order it.

@jeremystretch commented on GitHub (Mar 22, 2017): @ktims The evaluation needs to be done in SQL though. Otherwise, we'd have to dump the entire table to order it.
Author
Owner

@ktims commented on GitHub (Mar 22, 2017):

@jeremystretch Hrm, you're right, unless we store the full 8-byte value with the detected type instead of a string, and then decode that from binary. This shouldn't be all that hard to do with pure Postgres though, I've done IP->int conversion there before, and all the other bits are there, it just ends up a bit ugly. I'll take a stab at a Postgres function.

@ktims commented on GitHub (Mar 22, 2017): @jeremystretch Hrm, you're right, unless we store the full 8-byte value with the detected type instead of a string, and then decode that from binary. This shouldn't be all that hard to do with pure Postgres though, I've done IP->int conversion there before, and all the other bits are there, it just ends up a bit ugly. I'll take a stab at a Postgres function.
Author
Owner

@ktims commented on GitHub (Mar 23, 2017):

I wrote a Postgres function to turn the string representation of an RD into its canonical int8 representation. int8 types are used where they shouldn't be necessary due to Postgres' lack of unsigned types. This could be cleaned up and would improve validation with use of domains to implement unsigned types. I also implemented the reverse function to error check, and it may be useful if the choice is made to store internally as an int8 instead of VARCHAR(21).

Note that the first 2 bytes of the RD are the type specifier, so type 0 (ASN2:INT4) will always sort before type 1 (IP:INT2), which is likewise before type 2 (ASN4:INT2). This might not be the most desirable, but I hope each org is only using one of the 3 available types. I suppose a composite type could be created that would allow sorting by the integer representation of the administrator subfield, then the assigned number, but this seems a bit excessive.

https://gist.github.com/ktims/6cf9e5bb252b91c61309f554c9d8496d

@ktims commented on GitHub (Mar 23, 2017): I wrote a Postgres function to turn the string representation of an RD into its canonical int8 representation. int8 types are used where they shouldn't be necessary due to Postgres' lack of unsigned types. This could be cleaned up and would improve validation with use of domains to implement unsigned types. I also implemented the reverse function to error check, and it may be useful if the choice is made to store internally as an int8 instead of VARCHAR(21). Note that the first 2 bytes of the RD are the type specifier, so type 0 (ASN2:INT4) will always sort before type 1 (IP:INT2), which is likewise before type 2 (ASN4:INT2). This might not be the most desirable, but I hope each org is only using one of the 3 available types. I suppose a composite type could be created that would allow sorting by the integer representation of the administrator subfield, then the assigned number, but this seems a bit excessive. https://gist.github.com/ktims/6cf9e5bb252b91c61309f554c9d8496d
Author
Owner

@jeremystretch commented on GitHub (Mar 23, 2017):

@ktims That's very impressive! I'm not sure we want to add that degree of overhead though for what should be a simple query.

The larger issue is that we're attempting to normalize arbitrary data: a user can enter an RD of "foobar" just as easily as "65000:123". NetBox doesn't do any validation on the input, and that's probably an oversight on my part.

It might make more sense to implement RD validation now, and then create a migration to alter the column type in a future release (with some logic to prevent people from upgrading if incompatible values are found). Once that's done we could order records natively.

@jeremystretch commented on GitHub (Mar 23, 2017): @ktims That's very impressive! I'm not sure we want to add that degree of overhead though for what should be a simple query. The larger issue is that we're attempting to normalize arbitrary data: a user can enter an RD of "foobar" just as easily as "65000:123". NetBox doesn't do any validation on the input, and that's probably an oversight on my part. It might make more sense to implement RD validation now, and then create a migration to alter the column type in a future release (with some logic to prevent people from upgrading if incompatible values are found). Once that's done we could order records natively.
Author
Owner

@InsaneSplash commented on GitHub (Mar 27, 2017):

"Commander Keen" avatar +1 🥇

@InsaneSplash commented on GitHub (Mar 27, 2017): "Commander Keen" avatar +1 🥇
Author
Owner

@InsaneSplash commented on GitHub (May 19, 2017):

I see in v2.0.3 one is not able to sort the RD list anymore. Clicking on the RD table heading doesn't seem to change the sort order? Can you confirm this? I am keen to pick this thread up again.

@InsaneSplash commented on GitHub (May 19, 2017): I see in v2.0.3 one is not able to sort the RD list anymore. Clicking on the RD table heading doesn't seem to change the sort order? Can you confirm this? I am keen to pick this thread up again.
Author
Owner

@jeremystretch commented on GitHub (Oct 20, 2017):

Closing this out as it doesn't seem to be worth the effort needed to normalize the data.

@jeremystretch commented on GitHub (Oct 20, 2017): Closing this out as it doesn't seem to be worth the effort needed to normalize the data.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#785