| @@ 35-131 (lines=97) @@ | ||
| 32 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
| 33 | ||
| 34 | ||
| 35 | @BGPLS.register |
|
| 36 | class PREFIXv6(BGPLS): |
|
| 37 | CODE = 4 |
|
| 38 | NAME = "bgpls-prefix-v6" |
|
| 39 | SHORT_NAME = "PREFIX_V6" |
|
| 40 | ||
| 41 | def __init__ ( |
|
| 42 | self,domain,proto_id,local_node, |
|
| 43 | packed=None,ospf_type=None,prefix=None, |
|
| 44 | nexthop=None,route_d=None,action=None, addpath=None): |
|
| 45 | BGPLS.__init__(self,action,addpath) |
|
| 46 | self.domain = domain |
|
| 47 | self.ospf_type = ospf_type |
|
| 48 | self.proto_id = proto_id |
|
| 49 | self.local_node = local_node |
|
| 50 | self.prefix = prefix |
|
| 51 | self.nexthop = nexthop |
|
| 52 | self._pack = packed |
|
| 53 | self.route_d = route_d |
|
| 54 | ||
| 55 | @classmethod |
|
| 56 | def unpack_nlri (cls, data, rd): |
|
| 57 | ospf_type = None |
|
| 58 | proto_id = unpack('!B',data[0:1])[0] |
|
| 59 | if proto_id not in PROTO_CODES.keys(): |
|
| 60 | raise Exception('Protocol-ID {} is not valid'.format(proto_id)) |
|
| 61 | domain = unpack('!Q',data[1:9])[0] |
|
| 62 | tlvs = data[9:] |
|
| 63 | ||
| 64 | while tlvs: |
|
| 65 | tlv_type, tlv_length = unpack('!HH', tlvs[:4]) |
|
| 66 | if tlv_type == 256: |
|
| 67 | values = tlvs[4: 4 + tlv_length] |
|
| 68 | local_node = [] |
|
| 69 | while values: |
|
| 70 | # Unpack Local Node Descriptor Sub-TLVs |
|
| 71 | # We pass proto_id as TLV interpretation |
|
| 72 | # follows IGP type |
|
| 73 | node, left = NodeDescriptor.unpack(values, proto_id) |
|
| 74 | local_node.append(node) |
|
| 75 | if left == values: |
|
| 76 | raise RuntimeError("sub-calls should consume data") |
|
| 77 | values = left |
|
| 78 | tlvs = tlvs[4 + tlv_length:] |
|
| 79 | continue |
|
| 80 | if tlv_type == 264: |
|
| 81 | values = tlvs[4: 4 + tlv_length] |
|
| 82 | ospf_type = OspfRoute.unpack(values) |
|
| 83 | tlvs = tlvs[4 + tlv_length:] |
|
| 84 | if tlv_type == 265: |
|
| 85 | values = tlvs[4: 4 + tlv_length] |
|
| 86 | prefix = IpReach.unpack(values, 4) |
|
| 87 | tlvs = tlvs[4 + tlv_length:] |
|
| 88 | ||
| 89 | return cls( |
|
| 90 | domain=domain,proto_id=proto_id,packed=data, |
|
| 91 | local_node=local_node,ospf_type=ospf_type, |
|
| 92 | prefix=prefix,route_d=rd |
|
| 93 | ) |
|
| 94 | ||
| 95 | def __eq__ (self, other): |
|
| 96 | return \ |
|
| 97 | isinstance(other, PREFIXv6) and \ |
|
| 98 | self.CODE == other.CODE and \ |
|
| 99 | self.domain == other.domain and \ |
|
| 100 | self.proto_id == other.proto_id and \ |
|
| 101 | self.route_d == other.route_d |
|
| 102 | ||
| 103 | def __ne__ (self, other): |
|
| 104 | return not self.__eq__(other) |
|
| 105 | ||
| 106 | def __str__ (self): |
|
| 107 | return self.json() |
|
| 108 | ||
| 109 | def __hash__ (self): |
|
| 110 | return hash((self)) |
|
| 111 | ||
| 112 | def json (self, compact=None): |
|
| 113 | nodes = ', '.join(d.json() for d in self.local_node) |
|
| 114 | content = ', '.join([ |
|
| 115 | '"ls-nlri-type": "%s"' % self.NAME, |
|
| 116 | '"l3-routing-topology": %d' % int(self.domain), |
|
| 117 | '"protocol-id": %d' % int(self.proto_id), |
|
| 118 | '"node-descriptors": { %s }' % nodes, |
|
| 119 | self.prefix.json(), |
|
| 120 | '"nexthop": "%s"' % self.nexthop, |
|
| 121 | ]) |
|
| 122 | if self.ospf_type: |
|
| 123 | content += ', %s' % self.ospf_type.json() |
|
| 124 | ||
| 125 | if self.route_d: |
|
| 126 | content += ', %s' % self.route_d.json() |
|
| 127 | ||
| 128 | return '{ %s }' % (content) |
|
| 129 | ||
| 130 | def pack (self,negotiated=None): |
|
| 131 | return self._pack |
|
| @@ 34-130 (lines=97) @@ | ||
| 31 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
| 32 | ||
| 33 | ||
| 34 | @BGPLS.register |
|
| 35 | class PREFIXv4(BGPLS): |
|
| 36 | CODE = 3 |
|
| 37 | NAME = "bgpls-prefix-v4" |
|
| 38 | SHORT_NAME = "PREFIX_V4" |
|
| 39 | ||
| 40 | def __init__ ( |
|
| 41 | self,domain,proto_id,local_node, |
|
| 42 | packed=None,ospf_type=None,prefix=None, |
|
| 43 | nexthop=None,route_d=None,action=None, addpath=None): |
|
| 44 | BGPLS.__init__(self,action,addpath) |
|
| 45 | self.domain = domain |
|
| 46 | self.ospf_type = ospf_type |
|
| 47 | self.proto_id = proto_id |
|
| 48 | self.local_node = local_node |
|
| 49 | self.prefix = prefix |
|
| 50 | self.nexthop = nexthop |
|
| 51 | self._pack = packed |
|
| 52 | self.route_d = route_d |
|
| 53 | ||
| 54 | @classmethod |
|
| 55 | def unpack_nlri (cls, data, rd): |
|
| 56 | ospf_type = None |
|
| 57 | proto_id = unpack('!B',data[0:1])[0] |
|
| 58 | if proto_id not in PROTO_CODES.keys(): |
|
| 59 | raise Exception('Protocol-ID {} is not valid'.format(proto_id)) |
|
| 60 | domain = unpack('!Q',data[1:9])[0] |
|
| 61 | tlvs = data[9:] |
|
| 62 | ||
| 63 | while tlvs: |
|
| 64 | tlv_type, tlv_length = unpack('!HH', tlvs[:4]) |
|
| 65 | if tlv_type == 256: |
|
| 66 | values = tlvs[4: 4 + tlv_length] |
|
| 67 | local_node = [] |
|
| 68 | while values: |
|
| 69 | # Unpack Local Node Descriptor Sub-TLVs |
|
| 70 | # We pass proto_id as TLV interpretation |
|
| 71 | # follows IGP type |
|
| 72 | node, left = NodeDescriptor.unpack(values, proto_id) |
|
| 73 | local_node.append(node) |
|
| 74 | if left == values: |
|
| 75 | raise RuntimeError("sub-calls should consume data") |
|
| 76 | values = left |
|
| 77 | tlvs = tlvs[4 + tlv_length:] |
|
| 78 | continue |
|
| 79 | if tlv_type == 264: |
|
| 80 | values = tlvs[4: 4 + tlv_length] |
|
| 81 | ospf_type = OspfRoute.unpack(values) |
|
| 82 | tlvs = tlvs[4 + tlv_length:] |
|
| 83 | if tlv_type == 265: |
|
| 84 | values = tlvs[4: 4 + tlv_length] |
|
| 85 | prefix = IpReach.unpack(values, 3) |
|
| 86 | tlvs = tlvs[4 + tlv_length:] |
|
| 87 | ||
| 88 | return cls( |
|
| 89 | domain=domain,proto_id=proto_id,packed=data, |
|
| 90 | local_node=local_node,ospf_type=ospf_type, |
|
| 91 | prefix=prefix,route_d=rd |
|
| 92 | ) |
|
| 93 | ||
| 94 | def __eq__ (self, other): |
|
| 95 | return \ |
|
| 96 | isinstance(other, PREFIXv4) and \ |
|
| 97 | self.CODE == other.CODE and \ |
|
| 98 | self.domain == other.domain and \ |
|
| 99 | self.proto_id == other.proto_id and \ |
|
| 100 | self.route_d == other.route_d |
|
| 101 | ||
| 102 | def __ne__ (self, other): |
|
| 103 | return not self.__eq__(other) |
|
| 104 | ||
| 105 | def __str__ (self): |
|
| 106 | return self.json() |
|
| 107 | ||
| 108 | def __hash__ (self): |
|
| 109 | return hash((self)) |
|
| 110 | ||
| 111 | def json (self, compact=None): |
|
| 112 | nodes = ', '.join(d.json() for d in self.local_node) |
|
| 113 | content = ', '.join([ |
|
| 114 | '"ls-nlri-type": "%s"' % self.NAME, |
|
| 115 | '"l3-routing-topology": %d' % int(self.domain), |
|
| 116 | '"protocol-id": %d' % int(self.proto_id), |
|
| 117 | '"node-descriptors": { %s }' % nodes, |
|
| 118 | self.prefix.json(), |
|
| 119 | '"nexthop": "%s"' % self.nexthop, |
|
| 120 | ]) |
|
| 121 | if self.ospf_type: |
|
| 122 | content += ', %s' % self.ospf_type.json() |
|
| 123 | ||
| 124 | if self.route_d: |
|
| 125 | content += ', %s' % self.route_d.json() |
|
| 126 | ||
| 127 | return '{ %s }' % (content) |
|
| 128 | ||
| 129 | def pack (self,negotiated=None): |
|
| 130 | return self._pack |
|
| 131 | ||