1# encoding: utf-8
2"""
3community.py
4
5Created by Thomas Mangin on 2009-11-05.
6Copyright (c) 2009-2017 Exa Networks. All rights reserved.
7License: 3-clause BSD. (See the COPYRIGHT file)
8"""
9
10from struct import pack
11from struct import unpack
12
13
14# ==================================================================== Community
15#
16
17
18class Community(object):
19    MAX = 0xFFFFFFFF
20
21    NO_EXPORT = pack('!L', 0xFFFFFF01)
22    NO_ADVERTISE = pack('!L', 0xFFFFFF02)
23    NO_EXPORT_SUBCONFED = pack('!L', 0xFFFFFF03)
24    NO_PEER = pack('!L', 0xFFFFFF04)
25    BLACKHOLE = pack('!L', 0xFFFF029A)
26
27    cache = {}
28    caching = True
29
30    __slots__ = ['community', '_str']
31
32    def __init__(self, community):
33        self.community = community
34        if community == self.NO_EXPORT:
35            self._str = 'no-export'
36        elif community == self.NO_ADVERTISE:
37            self._str = 'no-advertise'
38        elif community == self.NO_EXPORT_SUBCONFED:
39            self._str = 'no-export-subconfed'
40        elif community == self.NO_PEER:
41            self._str = 'no-peer'
42        elif community == self.BLACKHOLE:
43            self._str = 'blackhole'
44        else:
45            self._str = "%d:%d" % unpack('!HH', self.community)
46
47    def __eq__(self, other):
48        return self.community == other.community
49
50    def __ne__(self, other):
51        return self.community != other.community
52
53    def __lt__(self, other):
54        return self.community < other.community
55
56    def __le__(self, other):
57        return self.community <= other.community
58
59    def __gt__(self, other):
60        return self.community > other.community
61
62    def __ge__(self, other):
63        return self.community >= other.community
64
65    def json(self):
66        return "[ %d, %d ]" % unpack('!HH', self.community)
67
68    def pack(self, negotiated=None):
69        return self.community
70
71    def __repr__(self):
72        return self._str
73
74    def __len__(self):
75        return 4
76
77    @classmethod
78    def unpack(cls, community, negotiated):
79        return cls(community)
80
81    @classmethod
82    def cached(cls, community):
83        if not cls.caching:
84            return cls(community)
85        if community in cls.cache:
86            return cls.cache[community]
87        instance = cls(community)
88        cls.cache[community] = instance
89        return instance
90
91
92# Always cache well-known communities, they will be used a lot
93if not Community.cache:
94    Community.cache[Community.NO_EXPORT] = Community(Community.NO_EXPORT)
95    Community.cache[Community.NO_ADVERTISE] = Community(Community.NO_ADVERTISE)
96    Community.cache[Community.NO_EXPORT_SUBCONFED] = Community(Community.NO_EXPORT_SUBCONFED)
97    Community.cache[Community.NO_PEER] = Community(Community.NO_PEER)
98    Community.cache[Community.BLACKHOLE] = Community(Community.BLACKHOLE)
99