Completed
Pull Request — master (#964)
by Thomas
13:14
created

SrAdjacency.unpack()   B

Complexity

Conditions 6

Size

Total Lines 33
Code Lines 18

Duplication

Lines 33
Ratio 100 %

Importance

Changes 0
Metric Value
cc 6
eloc 18
nop 3
dl 33
loc 33
rs 8.5666
c 0
b 0
f 0
1
# encoding: utf-8
2
"""
3
sradj.py
4
5
Created by Evelio Vila
6
Copyright (c) 2014-2017 Exa Networks. All rights reserved.
7
"""
8
9
import json
10
from struct import unpack
11
from exabgp.vendoring import six
12
from exabgp.util import hexstring
13
14
from exabgp.vendoring.bitstring import BitArray
15
from exabgp.bgp.message.update.attribute.bgpls.linkstate import LINKSTATE, LsGenericFlags
16
17
#    draft-gredler-idr-bgp-ls-segment-routing-ext-03
18
#    0                   1                   2                   3
19
#    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
20
#   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
21
#   |               Type            |              Length           |
22
#   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23
#   | Flags         |     Weight    |             Reserved          |
24
#   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
25
#   |                   SID/Label/Index (variable)                  |
26
#   +---------------------------------------------------------------+
27
#
28
29 View Code Duplication
@LINKSTATE.register()
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
30
class SrAdjacency(object):
31
	TLV = 1099
32
	_sr_adj_sids = []
33
34
	def __init__ (self):
35
		self.sr_adj_sids = SrAdjacency._sr_adj_sids.copy()
36
37
	def __repr__ (self):
38
		return "sr-adj-sids: {}".format(self.sr_adj_sids)
39
40
	@classmethod
41
	def unpack (cls,data,length):
42
		# We only support IS-IS flags for now.
43
		flags = LsGenericFlags.unpack(data[0:1],LsGenericFlags.ISIS_SR_ADJ_FLAGS).flags
44
		# Parse adj weight
45
		weight = six.indexbytes(data,1)
46
		# Move pointer 4 bytes: Flags(1) + Weight(1) + Reserved(2)
47
		data = data[4:]
48
     	# SID/Index/Label: according to the V and L flags, it contains
49
      	# either:
50
		# *  A 3 octet local label where the 20 rightmost bits are used for
51
		#	 encoding the label value.  In this case the V and L flags MUST
52
		#	 be set.
53
		#
54
		# *  A 4 octet index defining the offset in the SID/Label space
55
		# 	 advertised by this router using the encodings defined in
56
		#  	 Section 3.1.  In this case V and L flags MUST be unset.
57
		raw = []
58
		while data:
59
			# Range Size: 3 octet value indicating the number of labels in
60
			# the range.
61
			if int(flags['V']) and int(flags['L']):
62
				b = BitArray(bytes=data[:3])
63
				sid = b.unpack('uintbe:24')[0]
64
				data = data[3:]
65
			elif (not flags['V']) and (not flags['L']):
66
				sid = unpack('!I',data[:4])[0]
67
				data = data[4:]
68
			else:
69
				raw.append(hexstring(data))
70
				break
71
		cls._sr_adj_sids.append({'flags': flags, 'weight': weight, 'sid': sid, 'undecoded': raw})
0 ignored issues
show
introduced by
The variable sid does not seem to be defined in case the while loop on line 58 is not entered. Are you sure this can never be the case?
Loading history...
72
		return cls()
73
74
	def json (self,compact=None):
75
		return '"sr-adj-sids": {}'.format(json.dumps(self.sr_adj_sids))
76
77
	@classmethod
78
	def reset(cls):
79
		cls._sr_adj_sids = []
80