Statistics
| Branch: | Revision:

iof-tools / confFileGenerator / Edge.py @ 7c83f065

History | View | Annotate | Download (11.9 KB)

1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3

    
4
# This program is free software: you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
#
17
# Copyright (C) 2019  Mattia Milani <mattia.milani@studenti.unitn.it>
18

    
19
import ipaddress
20
import constants
21
from constants import *
22
import os.path
23

    
24

    
25
# Class to manage edges
26
class Edge:
27
    # Class variables to manage networks
28
    nodeIpNetworks_externalEth = list(ipaddress.ip_network(u'10.0.0.0/12').subnets(new_prefix=30))
29
    counter_external_networks = 0
30

    
31
    def __init__(self, node1, node2, _type, addresses, out1, out2):
32
        if len(addresses) != 2:
33
            raise exception('invalid addresses parameter, addresses is a list of exactly two str ips')
34

    
35
        self.node1 = node1
36
        self.node2 = node2
37
        if addresses[0] != "" and addresses[1] != "":
38
            self.node1Eth = ipaddress.IPv4Interface(addresses[0])
39
            self.node2Eth = ipaddress.IPv4Interface(addresses[1])
40

    
41
            if self.node1Eth.network != self.node2Eth.network:
42
                raise Exception('invalid addresses parameter, addresses needs to belong to the same network')
43
            if self.node1Eth.netmask != self.node2Eth.netmask or int(self.node1Eth.netmask) != 4294967292:
44
                raise Exception('invalid addresses parameter, addresses needs to belong to a /30 network')
45

    
46
            self.edge_network = self.node1Eth.network
47
            self.node1.set_new_external_addr(self.node2, self.node1Eth.ip)
48
            self.node2.set_new_external_addr(self.node1, self.node2Eth.ip)
49
        else:
50
            # If this edge was not created before I need a new network, and to assign the addresses
51
            # to the node interfaces
52
            if self.counter_external_networks < len(self.nodeIpNetworks_externalEth) and \
53
                    (self.node1.get_external_addr(self.node2) is None and self.node2.get_external_addr(
54
                        self.node1) is None):
55
                # Get the network
56
                self.edge_network = Edge.nodeIpNetworks_externalEth[Edge.counter_external_networks]
57
                Edge.counter_external_networks += 1
58
                # Assign addresses
59
                self.node1.set_new_external_addr(self.node2, self.edge_network[1])
60
                self.node2.set_new_external_addr(self.node1, self.edge_network[2])
61
            elif self.counter_external_networks >= len(self.nodeIpNetworks_externalEth):
62
                raise ValueError('No more networks available for edges')
63
        self.type = _type
64
        self.outFolder1 = out1
65
        self.outFolder2 = out2
66

    
67
        # Conf files name for this edge
68
        self.bgpSessionFile1_name = "bgpSession_h_" + str(self.node1.name) + "_h_" + str(self.node2.name) + ".conf"
69
        self.bgpSessionFile2_name = "bgpSession_h_" + str(self.node2.name) + "_h_" + str(self.node1.name) + ".conf"
70

    
71
        # Predefined templates
72
        with open(BGP_SESSION_EXPORTER_TEMPLATE_PATH, "r") as bgp_file:
73
            self.bgp_session = bgp_file.read()
74
        with open(BGP_SESSION_STATIC_EXPORTER_TEMPLATE_PATH_UPLINKS, "r") as bgp_file:
75
            self.bgp_session_static_uplinks = bgp_file.read()
76
        with open(BGP_SESSION_STATIC_EXPORTER_TEMPLATE_PATH_PEERS, "r") as bgp_file:
77
            self.bgp_session_static_peers = bgp_file.read()
78
        with open(BGP_SESSION_STATIC_EXPORTER_TEMPLATE_PATH_CLIENTS, "r") as bgp_file:
79
            self.bgp_session_static_clients = bgp_file.read()
80

    
81
        # Add the node to the node set depending on the edge type
82
        if self.type == "transit":
83
            self.node1.add_servicer(self.node2)
84
            self.node2.add_customer(self.node1)
85
        elif self.type == "peer":
86
            self.node1.add_peer(self.node2)
87
            self.node2.add_peer(self.node1)
88
        else:
89
            raise ValueError("Type not correct, it's possible to use only transit and peer")
90

    
91
        # Open the files for the edge
92
        self.bgpSessionFile1 = open(self.outFolder1 + self.bgpSessionFile1_name, 'w+')
93
        self.bgpSessionFile2 = open(self.outFolder2 + self.bgpSessionFile2_name, 'w+')
94

    
95
    def __str__(self):
96
        return str(self.node1) + " <-> " + str(self.node2)
97

    
98
    # Function to export only to some nodes the information, depending on the edge type
99
    def write_static_exporter(self):
100
        lst = self.node1.get_customers_addresses()
101
        client_list = ""
102
        if len(lst) > 0:
103
            client_list = "return bgp_next_hop ~ " + str(lst).replace("'", "") + ";"
104

    
105
        lst = self.node2.get_customers_addresses()
106
        client_list2 = ""
107
        if len(lst) > 0:
108
            client_list2 = "return bgp_next_hop ~ " + str(lst).replace("'", "") + ";"
109

    
110
        mrai_content1 = ""
111
        mrai_content2 = ""
112

    
113
        if self.node1.mrai != 0:
114
            mrai_content1 = self.node1.mrai_template.format(mrai_timer=self.node1.mrai, mrai_type=constants.mrai_type)
115
        if self.node2.mrai != 0:
116
            mrai_content2 = self.node2.mrai_template.format(mrai_timer=self.node2.mrai, mrai_type=constants.mrai_type)
117

    
118
        if self.type == "transit":
119
            # Write the exporter file
120
            self.write_session_static_exporter_uplinks(self.bgpSessionFile1, str(client_list), "h_" +
121
                                                       str(self.node1.name) + "_" + "h_" + str(self.node2.name),
122
                                                       self.node1.get_external_addr(self.node2),
123
                                                       str(int(self.node1.name) + 1),
124
                                                       self.node2.get_external_addr(self.node1),
125
                                                       str(int(self.node2.name) + 1), mrai_content1, str(1))
126
            # Include the file in the node main file
127
            self.node1.include_in_main(self.bgpSessionFile1_name)
128
            self.write_session_static_exporter_clients(self.bgpSessionFile2, "h_" + str(self.node2.name) + "_" + "h_"
129
                                                       + str(self.node1.name), self.node2.get_external_addr(self.node1),
130
                                                       str(int(self.node2.name) + 1),
131
                                                       self.node1.get_external_addr(self.node2),
132
                                                       str(int(self.node1.name) + 1), mrai_content2, str(1))
133
            # Include file in the node main file
134
            self.node2.include_in_main(self.bgpSessionFile2_name)
135
        if self.type == "peer":
136
            # Write the exporter file
137
            self.write_session_static_exporter_peers(self.bgpSessionFile1, str(client_list), "h_" + str(self.node1.name)
138
                                                     + "_" + "h_" + str(self.node2.name),
139
                                                     self.node1.get_external_addr(self.node2),
140
                                                     str(int(self.node1.name) + 1),
141
                                                     self.node2.get_external_addr(self.node1),
142
                                                     str(int(self.node2.name) + 1), mrai_content1, str(1))
143
            # Include the file in the node main file
144
            self.node1.include_in_main(self.bgpSessionFile1_name)
145
            self.write_session_static_exporter_peers(self.bgpSessionFile2, str(client_list2), "h_" + str(self.node2.name)
146
                                                     + "_" + "h_" + str(self.node1.name),
147
                                                     self.node2.get_external_addr(self.node1),
148
                                                     str(int(self.node2.name) + 1),
149
                                                     self.node1.get_external_addr(self.node2),
150
                                                     str(int(self.node1.name) + 1), mrai_content2, str(1))
151
            # Include the file in the node main file
152
            self.node2.include_in_main(self.bgpSessionFile2_name)
153

    
154
    # Write session exporter with a predefined export politics
155
    def write_session_static_exporter_uplinks(self, file, clients_list, protocol_name, local_addr, local_as, neigh_addr,
156
                                              neigh_as, mrai_content, bgp_local_pref):
157
        file.write(self.bgp_session_static_uplinks.format(rt_export_name="rt_export_" + protocol_name,
158
                                                          client_list=clients_list, filter_in_name="filter_in_" +
159
                                                          protocol_name, filter_out_name="filter_out_" + protocol_name,
160
                                                          peer_as_filter=neigh_as, protocol_name=protocol_name,
161
                                                          local_addr=local_addr, local_as=local_as,
162
                                                          peer_addr=neigh_addr, peer_as=neigh_as, hold_timer=HOLD_TIMER,
163
                                                          mrai=mrai_content, connect_retry_timer=CONNECT_RETRY_TIMER,
164
                                                          connect_delay_timer=CONNECT_DELAY_TIMER,
165
                                                          startup_hold_timer=STARTUP_HOLD_TIMER,
166
                                                          local_pref=bgp_local_pref))
167

    
168
    def write_session_static_exporter_peers(self, file, clients_list, protocol_name, local_addr, local_as, neigh_addr,
169
                                            neigh_as, mrai_content, bgp_local_pref):
170
        file.write(self.bgp_session_static_peers.format(rt_export_name="rt_export_" + protocol_name,
171
                                                        client_list=clients_list, filter_in_name="filter_in_" +
172
                                                        protocol_name, filter_out_name="filter_out_" + protocol_name,
173
                                                        peer_as_filter=neigh_as, protocol_name=protocol_name,
174
                                                        local_addr=local_addr, local_as=local_as, peer_addr=neigh_addr,
175
                                                        peer_as=neigh_as, hold_timer=HOLD_TIMER, mrai=mrai_content,
176
                                                        connect_retry_timer=CONNECT_RETRY_TIMER,
177
                                                        connect_delay_timer=CONNECT_DELAY_TIMER,
178
                                                        startup_hold_timer=STARTUP_HOLD_TIMER,
179
                                                        local_pref=bgp_local_pref))
180

    
181
    def write_session_static_exporter_clients(self, file, protocol_name, local_addr, local_as, neigh_addr, neigh_as,
182
                                              mrai_content, bgp_local_pref):
183
        file.write(self.bgp_session_static_clients.format(filter_in_name="filter_in_" + protocol_name,
184
                                                          filter_out_name="filter_out_" + protocol_name,
185
                                                          peer_as_filter=neigh_as, protocol_name=protocol_name,
186
                                                          local_addr=local_addr, local_as=local_as,
187
                                                          peer_addr=neigh_addr, peer_as=neigh_as, hold_timer=HOLD_TIMER,
188
                                                          mrai=mrai_content, connect_retry_timer=CONNECT_RETRY_TIMER,
189
                                                          connect_delay_timer=CONNECT_DELAY_TIMER,
190
                                                          startup_hold_timer=STARTUP_HOLD_TIMER,
191
                                                          local_pref=bgp_local_pref))