Completed
Push — master ( 25ce4f...b9bc4f )
by Thomas
11:58
created

AnnounceVPN._check()   A

Complexity

Conditions 2

Size

Total Lines 4
Code Lines 4

Duplication

Lines 4
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nop 1
dl 4
loc 4
rs 10
c 0
b 0
f 0
1
# encoding: utf-8
2
"""
3
announce/vpn.py
4
5
Created by Thomas Mangin on 2017-07-05.
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.ip import NoNextHop
11
12
from exabgp.rib.change import Change
13
14
from exabgp.bgp.message import OUT
15
16
from exabgp.protocol.family import AFI
17
from exabgp.protocol.family import SAFI
18
19
from exabgp.bgp.message.update.nlri import IPVPN
20
from exabgp.bgp.message.update.nlri.cidr import CIDR
21
from exabgp.bgp.message.update.nlri.qualifier import RouteDistinguisher
22
from exabgp.bgp.message.update.attribute import Attributes
23
24
from exabgp.configuration.announce import ParseAnnounce
25
from exabgp.configuration.announce.label import AnnounceLabel
26
27
from exabgp.configuration.static.parser import prefix
28
from exabgp.configuration.static.mpls import route_distinguisher
29
30
31
class AnnounceVPN (ParseAnnounce):
32
	# put next-hop first as it is a requirement atm
33
	definition = [
34
		'  (optional) rd 255.255.255.255:65535|65535:65536|65536:65535;\n',
35
	] + AnnounceLabel.definition
36
37
	syntax = \
38
		'<safi> <ip>/<netmask> { ' \
39
		'\n   ' + ' ;\n   '.join(definition) + '\n}'
40
41
	known = dict(AnnounceLabel.known,**{
42
		'rd':                   route_distinguisher,
43
	})
44
45
	action = dict(AnnounceLabel.action,**{
46
		'rd':                  'nlri-set',
47
	})
48
49
	assign = dict(AnnounceLabel.assign,**{
50
		'rd':                  'rd',
51
	})
52
53
	name = 'vpn'
54
	afi = None
55
56
	def __init__ (self, tokeniser, scope, error, logger):
57
		ParseAnnounce.__init__(self,tokeniser,scope,error,logger)
58
59
	def clear (self):
60
		return True
61
62
	@staticmethod
63
	def check (change,afi):
64
		if not AnnounceLabel.check(change,afi):
65
			return False
66
67
		if change.nlri.action == OUT.ANNOUNCE \
68
			and change.nlri.has_rd() \
69
			and change.nlri.rd is RouteDistinguisher.NORD:
70
			return False
71
72
		return True
73
74
75 View Code Duplication
def ip_vpn (tokeniser,afi,safi):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
76
	action = OUT.ANNOUNCE if tokeniser.announce else OUT.WITHDRAW
77
	ipmask = prefix(tokeniser)
78
79
	nlri = IPVPN(afi, safi, action)
80
	nlri.cidr = CIDR(ipmask.pack(),ipmask.mask)
81
82
	change = Change(
83
		nlri,
84
		Attributes()
85
	)
86
87
	while True:
88
		command = tokeniser()
89
90
		if not command:
91
			break
92
93
		action = AnnounceVPN.action.get(command,'')
94
95
		if action == 'attribute-add':
96
			change.attributes.add(AnnounceVPN.known[command](tokeniser))
97
		elif action == 'nlri-set':
98
			change.nlri.assign(AnnounceVPN.assign[command],AnnounceVPN.known[command](tokeniser))
99
		elif action == 'nexthop-and-attribute':
100
			nexthop,attribute = AnnounceVPN.known[command](tokeniser)
101
			change.nlri.nexthop = nexthop
102
			change.attributes.add(attribute)
103
		else:
104
			raise ValueError('unknown command "%s"' % command)
105
106
	if not AnnounceVPN.check(change,afi):
107
		raise ValueError('invalid announcement (missing next-hop, label or rd ?)')
108
109
	return [change]
110
111
112
@ParseAnnounce.register('mpls-vpn','extend-name','ipv4')
113
def mpls_vpn_v4 (tokeniser):
114
	return ip_vpn(tokeniser,AFI.ipv4,SAFI.unicast)
115
116
117
@ParseAnnounce.register('mpls-vpn','extend-name','ipv6')
118
def mpls_vpn_v6 (tokeniser):
119
	return ip_vpn(tokeniser,AFI.ipv6,SAFI.unicast)
120