Completed
Push — master ( 0517dc...c6929c )
by Thomas
24:49 queued 09:50
created

exabgp.bgp.message.update.nlri.nlri   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 109
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 66
dl 0
loc 109
rs 10
c 0
b 0
f 0
wmc 20

16 Methods

Rating   Name   Duplication   Size   Complexity  
A NLRI.__gt__() 0 2 1
A NLRI.__ne__() 0 2 1
A NLRI.assign() 0 2 1
A NLRI.__ge__() 0 2 1
A NLRI.__init__() 0 3 1
A NLRI.__lt__() 0 2 1
A NLRI.__eq__() 0 2 1
A NLRI.__le__() 0 2 1
A NLRI.__hash__() 0 2 1
A NLRI.feedback() 0 2 1
A NLRI.pack() 0 2 1
A NLRI.index() 0 2 1
A NLRI.register() 0 17 3
A NLRI.pack_nlri() 0 2 1
A NLRI.known_families() 0 5 1
A NLRI.unpack_nlri() 0 12 3
1
# encoding: utf-8
2
"""
3
nlri.py
4
5
Created by Thomas Mangin on 2012-07-08.
6
Copyright (c) 2009-2017 Exa Networks. All rights reserved.
7
License: 3-clause BSD. (See the COPYRIGHT file)
8
"""
9
10
from exabgp.protocol.family import AFI
11
from exabgp.protocol.family import SAFI
12
from exabgp.protocol.family import Family
13
from exabgp.bgp.message import OUT
14
from exabgp.bgp.message.notification import Notify
15
16
from exabgp.logger import Logger
17
from exabgp.logger import LazyNLRI
18
19
20
class NLRI(Family):
21
    __slots__ = ['action']
22
23
    EOR = False
24
25
    registered_nlri = dict()
26
    registered_families = [(AFI.ipv4, SAFI.multicast)]
27
    logger = None
28
29
    def __init__(self, afi, safi, action=OUT.UNSET):
30
        Family.__init__(self, afi, safi)
31
        self.action = action
32
33
    def __hash__(self):
34
        return hash("%s:%s:%s" % (self.afi, self.safi, self.pack_nlri()))
35
36
    def __eq__(self, other):
37
        return self.index() == other.index()
38
39
    def __ne__(self, other):
40
        return self.index() != other.index()
41
42
    # does not really make sense but allows to get the NLRI in a
43
    # deterministic order when generating update (Good for testing)
44
45
    def __lt__(self, other):
46
        return self.index() < other.index()
47
48
    def __le__(self, other):
49
        return self == other or self.index() < other.index()
50
51
    def __gt__(self, other):
52
        return self.index() > other.index()
53
54
    def __ge__(self, other):
55
        return self == other or self.index() > other.index()
56
57
    def feedback(self, action):
58
        raise RuntimeError('feedback is not implemented')
59
60
    def assign(self, name, value):
61
        setattr(self, name, value)
62
63
    def index(self):
64
        return Family.index(self) + self.pack_nlri()
65
66
    # remove this when code restructure is finished
67
    def pack(self, negotiated=None):
68
        return self.pack_nlri(negotiated)
69
70
    def pack_nlri(self, negotiated=None):
71
        raise Exception('unimplemented in NLRI children class')
72
73
    @classmethod
74
    def register(cls, afi, safi, force=False):
75
        def register_nlri(klass):
76
            new = (AFI.create(afi), SAFI.create(safi))
77
            if new in cls.registered_nlri:
78
                if force:
79
                    # python has a bug and does not allow %ld/%ld (pypy does)
80
                    cls.registered_nlri['%s/%s' % new] = klass
81
                else:
82
                    raise RuntimeError('Tried to register %s/%s twice' % new)
83
            else:
84
                # python has a bug and does not allow %ld/%ld (pypy does)
85
                cls.registered_nlri['%s/%s' % new] = klass
86
                cls.registered_families.append(new)
87
            return klass
88
89
        return register_nlri
90
91
    @staticmethod
92
    def known_families():
93
        # we do not want to take the risk of the caller modifying the list by accident
94
        # it can not be a generator
95
        return list(NLRI.registered_families)
96
97
    @classmethod
98
    def unpack_nlri(cls, afi, safi, data, action, addpath):
99
        if not cls.logger:
100
            cls.logger = Logger()
101
102
        a, s = AFI.create(afi), SAFI.create(safi)
103
        cls.logger.debug(LazyNLRI(a, s, addpath, data), 'parser')
104
105
        key = '%s/%s' % (a, s)
106
        if key in cls.registered_nlri:
107
            return cls.registered_nlri[key].unpack_nlri(a, s, data, action, addpath)
108
        raise Notify(3, 0, 'trying to decode unknown family %s/%s' % (a, s))
109