Revision de0e8e06

View differences:

BGPpysim/.gitignore
1
out/
2
__pycache__/
BGPpysim/bgpSimlulator.py
1
from argparse import ArgumentParser
2
import networkx as nx
3
from pprint import pprint
4
from util.EventScheduler import EventScheduler
5
from util.node import Node
6
from time import sleep
7
from tqdm import tqdm
8
import random
9
import sys
10
import datetime
11
import os
12
import shutil
13
from util.routing_table import Route
14
import code  # code.interact(local=dict(globals(), **locals()))
15

  
16
MAX_DURATION = 100
17

  
18

  
19
class bgpSim(object):
20

  
21
    def __init__(self, graph, sim_dir):
22
        self.G = graph
23
        self.sim_dir = sim_dir
24
        self.initNodes(G)
25

  
26
    def initNodes(self, G):
27
        print("InitNodes")
28
        nodes = {}
29
        # Node attributes
30
        for n in self.G.nodes(data=True):
31
            node_id = n[0]
32
            node_type, prefixes = 'C', []
33
            if 'type' in n[1]:
34
                node_type = n[1]['type']
35
            if 'destinations' in n[1]:
36
                prefixes = n[1]['destinations'].split(',')
37
            nodes[node_id] = Node(node_id, self.sim_dir, node_type, prefixes)
38

  
39
        # Edge attributes
40
        for e in self.G.edges(data=True):
41
            #source, target = e[0], e[1]
42
            edge_type, end1, end2, mrai1, mrai2, customer = e[2]['type'], e[2]['termination1'], e[
43
                2]['termination2'], float(e[2]['mrai1']), float(e[2]['mrai2']), e[2]['customer']
44
            if edge_type == 'peer':
45
                nodes[end1].neighs[end2] = {
46
                    'relation': 'peer', 'mrai': mrai1, 'pynode': nodes[end2]}
47
                nodes[end2].neighs[end1] = {
48
                    'relation': 'peer', 'mrai': mrai2, 'pynode': nodes[end1]}
49
            elif edge_type == 'transit':
50
                c, p = (end1, end2) if customer == end1 else (end2, end1)
51
                p2c, c2p = (mrai1, mrai2) if customer == end1 else (
52
                    mrai2, mrai1)
53
                # my neigh is my provider
54
                nodes[c].neighs[p] = {
55
                    'relation': 'provider', 'mrai': c2p, 'pynode': nodes[p]}
56
                # my neigh is my customer
57
                nodes[p].neighs[c] = {
58
                    'relation': 'customer', 'mrai': p2c, 'pynode': nodes[c]}
59
        self.nodes = nodes
60

  
61
    def jitter(self):
62
        return [-1, 1][random.randrange(2)]*random.uniform(0, 0.866)
63

  
64
    def scedule_initial_events(self, sched):
65
        for nodeID in self.nodes:
66
            sched.schedule_event(
67
                1.0 + self.jitter(), {'actor': nodeID, 'action': 'CHECK_RX'})
68
            '''if self.nodes[nodeID].exportPrefixes:
69
                # Primo annuncio a tutti i vicini
70
                for prefix in self.nodes[nodeID].exportPrefixes:
71
                    for neigh in self.nodes[nodeID].neighs:
72
                        route = Route(prefix, {'AS_PATH': nodeID})
73
                        sched.schedule_event(
74
                            0.0 + self.jitter(), {'actor': nodeID,
75
                                           'action': 'MRAI_DEADLINE', 'route': route, 'neigh': neigh})'''
76

  
77
    def runSimulation(self):
78
        sched = EventScheduler()
79
        self.scedule_initial_events(sched)
80
        print("Simulation started")
81
        time = 0
82
        with tqdm(total=MAX_DURATION) as pbar:
83
            while(sched.elapsed_time() < MAX_DURATION and len(sched.queue) > 0):
84
                event = sched.pop_event()
85
                current_time = sched.elapsed_time()
86
                node = self.nodes[event['actor']]
87
                # code.interact(local=dict(globals(), **locals()))
88
                if event['action'] == 'CHECK_RX':
89
                    node.processRXupdates(sched.elapsed_time())
90
                    # reschedule same event of type 'CHECK_RX'
91
                    sched.schedule_event(current_time + self.jitter(), event)
92
                elif event['action'] == 'MRAI_DEADLINE':
93
                    node.sendUpdate(
94
                        event['route'], event['neigh'], sched.elapsed_time())
95
                sleep(0.1)
96
                time += 10
97
                pbar.update(1)
98

  
99

  
100
def config_out_path(outPath):
101
    if not os.path.exists(outPath):
102
        raise Exception("\u001b[31mCannot find the outpath you provided!\n")
103
    else:
104
        start = datetime.datetime.now().strftime("%Hh%Mm%Ss_%d-%m-%Y")
105
        cdir = outPath + '/' + 'bgpSim_' + start
106
        if os.path.exists(cdir):
107
            shutil.rmtree(cdir)
108
        os.makedirs(cdir)
109
        return cdir
110

  
111

  
112
if __name__ == '__main__':
113
    # Define and get required args
114
    parser = ArgumentParser()
115
    parser.add_argument("-g", "--graph",
116
                        dest="graph", required=True, action="store",
117
                        help="Graph topology describer, .graphml format.")
118
    parser.add_argument("-w", "--write-to", dest="writeto",
119
                        default="out/", action="store",
120
                        help="Output folder for simulation")
121
    args = parser.parse_args()
122
    graph_path = args.graph
123
    output_folder = args.writeto
124
    sim_dir = config_out_path(output_folder)
125

  
126
    G = nx.read_graphml(path=graph_path)
127

  
128
    # Initialize simulator and start simulation
129
    sim = bgpSim(G, sim_dir)
130
    sim.runSimulation()
131
    print("FINISHED SIMULATION, MAX TIME OR CONVERGENCE REACHED")
132
    for n in sim.nodes.values():
133
        print("RT of NODE: "+n.ID)
134
        n.RT.dumps()
135
    code.interact(local=dict(globals(), **locals()))
BGPpysim/fabrex1.edgelist
1
S,		T, Weight
2
SOURCE	X1	1
3
X1		X2	1
4
X1		Y1	1
5
X2		X3	1
6
X2		Y2	1
7
X3		Y3	1
8
X3		X4	1
BGPpysim/genFABREXfig1.py
1
#!/usr/bin/python
2

  
3
import code
4
import networkx as nx
5
from collections import defaultdict
6

  
7

  
8
def edge(e1, e2, etype, mrai1=30, mrai2=30, customer=None):
9
    if etype == 'peer':
10
        assert customer == None
11
    elif etype == 'transit':
12
        assert customer == e1 or customer == e2
13
    redge = (e1, e2, {'type': etype, 'termination1': e1, 'termination2': e2,
14
                      'mrai1': mrai1, 'mrai2': mrai2, 'customer': customer})
15
    return redge
16

  
17

  
18
G = nx.DiGraph()
19

  
20
etype = 'transit'
21
myedges = []
22
myedges.append(edge('X4', 'Y3', etype, customer='X4', mrai1=7.5, mrai2=7.5))
23
myedges.append(edge('X4', 'X3', etype, customer='X4', mrai1=7.5, mrai2=7.5))
24
myedges.append(edge('Y3', 'X3', etype, customer='Y3', mrai1=7.5, mrai2=7.5))
25

  
26
myedges.append(edge('X3', 'Y2', etype, customer='X3', mrai1=15.0, mrai2=15.0))
27
myedges.append(edge('X3', 'X2', etype, customer='X3', mrai1=15.0, mrai2=15.0))
28
myedges.append(edge('Y2', 'X2', etype, customer='Y2', mrai1=15.0, mrai2=15.0))
29

  
30
myedges.append(edge('X2', 'Y1', etype, customer='X2', mrai1=30.0, mrai2=30.0))
31
myedges.append(edge('X2', 'X1', etype, customer='X2', mrai1=30.0, mrai2=30.0))
32
myedges.append(edge('Y1', 'X1', etype, customer='Y1', mrai1=30.0, mrai2=30.0))
33

  
34

  
35
G.add_edges_from(myedges)
36

  
37
attrs = defaultdict(dict)
38
# Source export dest d
39
ntype = 'C'
40
for n in G.nodes():
41
    destinations = []
42
    if n == 'X1':
43
        destinations = ['100.0.0.0/24']
44
    attrs[n]['destinations'] = ','.join(destinations)
45
    attrs[n]['type'] = ntype
46

  
47
nx.set_node_attributes(G, attrs)
48

  
49
nx.write_graphml(G, 'test.graphml')
50
#code.interact(local=dict(globals(), **locals()))
BGPpysim/policy.py
1
'''
2
Here the policy used by all nodes to compute
3
the routes' preference is defined...
4
Change the function if you want to implement a different policy!
5
The current policy implements exactly the 'binary' policy
6
of the Fabrikant-Rexford paper
7

  
8
The preference table in the policy function lists the binary labels of paths before
9
X1 changes the advertisment of d.
10
- X1 starts advertising d via the AS_PATH = 'X1' which initially costs 11
11
- Then X1 will advertise d via the AS_PATH = 'P,X1' (prepending), which model the
12
change of cost between X1 and d. The cost will become 01... the cost of those paths starting with 01
13
...
14
'''
15

  
16
#aspath = rxaaspath ^ rxID
17
from util.routing_table import Route
18
import code  # code.interact(local=dict(globals(), **locals()))
19

  
20

  
21
def policy(nodeID, route):
22
    LOWEST_PREF = 0
23
    if 'AS_PATH' not in route.attr:
24
        return LOWEST_PREF
25
    aspath = route.as_path() + "," + nodeID
26
    state = 'START'
27
    bs = ""
28
    #code.interact(local=dict(globals(), **locals()))
29
    for c in aspath.split(","):
30
        if state == 'START' and 'X' in c:
31
            bs += '1'
32
            state = 'A'
33
        elif state == 'START' and 'P' in c:
34
            state = 'B'
35
        elif state == 'A' and 'X' in c:
36
            bs += '1'
37
        elif state == 'A' and 'Y' in c:
38
            state = 'B'
39
        elif state == 'B' and 'X' in c:
40
            bs += '0'
41
            state = 'C'
42
        elif state == 'C' and 'X' in c:
43
            bs += '1'
44
            state = 'A'
45
    #print('BS =', bs)
46
    return int('0b'+bs, 2)
47

  
48

  
49
if __name__ == "__main__":
50
    route = ('dest', {'AS_PATH': 'X1,X2'})
51
    while(1):
52
        cost = policy(route)
53
        bincost = bin(cost)[2:]
54
        print("The cost of", route[1]['AS_PATH'], "is:")
55
        print("DEC =", cost, "\tBIN =", bincost)
56
        print("insert new AS_PATH to continue.")
57
        route[1]['AS_PATH'] = input()
58
#code.interact(local=dict(globals(), **locals()))
59

  
60
'''# Preference Table
61
    prefTab = {
62
        'X1': 11,
63
        'X1,Y1': 10,
64
        'X1,X2': 111,
65
        'X1,X2,Y2': 110,
66
        'X1,Y1,X2': 101,
67
        'X1,Y1,X2,Y2': 100,
68
        'X1,X2,X3': 1111,
69
        'X1,X2,X3,Y3': 1110,
70
        'X1,X2,Y2,X3': 1101,
71
        'X1,X2,Y2,X3,Y3': 1100,
72
        'X1,Y1,X2,X3': 1011,
73
        'X1,Y1,X2,X3,Y3': 1010,
74
        'X1,Y1,X2,Y2,X3': 1001,
75
        'X1,Y1,X2,Y2,X3,Y3': 1000,
76
    }
77

  
78
    if not aspath.startswith('X1,X1'):
79
        return int('0b'+str(prefTab[aspath]), 2)
80
    else:
81
        fakepath = ",".join(aspath.split(',')[1:])
82
        fakecost = str(prefTab[fakepath])
83
        #code.interact(local=dict(globals(), **locals()))
84
        return int('0b'+'0'+fakecost[1:], 2)'''
BGPpysim/topos/genFABREXfig1.py
1
#!/usr/bin/python
2

  
3
import code
4
import networkx as nx
5
from collections import defaultdict
6

  
7

  
8
def edge(e1, e2, etype, mrai1=30, mrai2=30, customer=None):
9
    if etype == 'peer':
10
        assert customer == None
11
    elif etype == 'transit':
12
        assert customer == e1 or customer == e2
13
    redge = (e1, e2, {'type': etype, 'termination1': e1, 'termination2': e2,
14
                      'mrai1': mrai1, 'mrai2': mrai2, 'customer': customer})
15
    return redge
16

  
17

  
18
G = nx.DiGraph()
19

  
20
etype = 'transit'
21
myedges = []
22
myedges.append(edge('X4', 'Y3', etype, customer='X4', mrai1=7.5, mrai2=7.5))
23
myedges.append(edge('X4', 'X3', etype, customer='X4', mrai1=7.5, mrai2=7.5))
24
myedges.append(edge('Y3', 'X3', etype, customer='Y3', mrai1=7.5, mrai2=7.5))
25

  
26
myedges.append(edge('X3', 'Y2', etype, customer='X3', mrai1=15.0, mrai2=15.0))
27
myedges.append(edge('X3', 'X2', etype, customer='X3', mrai1=15.0, mrai2=15.0))
28
myedges.append(edge('Y2', 'X2', etype, customer='Y2', mrai1=15.0, mrai2=15.0))
29

  
30
myedges.append(edge('X2', 'Y1', etype, customer='X2', mrai1=30.0, mrai2=30.0))
31
myedges.append(edge('X2', 'X1', etype, customer='X2', mrai1=30.0, mrai2=30.0))
32
myedges.append(edge('Y1', 'X1', etype, customer='Y1', mrai1=30.0, mrai2=30.0))
33

  
34

  
35
G.add_edges_from(myedges)
36

  
37
attrs = defaultdict(dict)
38
# Source export dest d
39
ntype = 'C'
40
for n in G.nodes():
41
    destinations = []
42
    if n == 'X1':
43
        destinations = ['100.0.0.0/24']
44
    attrs[n]['destinations'] = ','.join(destinations)
45
    attrs[n]['type'] = ntype
46

  
47
nx.set_node_attributes(G, attrs)
48

  
49
nx.write_graphml(G, 'test.graphml')
50
#code.interact(local=dict(globals(), **locals()))
BGPpysim/util/EventScheduler.py
1
import heapq
2

  
3
class EventScheduler:
4
        def __init__(self):
5
                self.queue = []
6
                self.time = 0
7
                self.last = 0
8
                self._step = 0
9
                self.counter = 0
10

  
11
        def schedule_event(self, interval, e):
12
                t = self.time + interval
13
                if t > self.last:
14
                    self.last = t
15
                heapq.heappush(self.queue, (t, e))
16

  
17
        def pop_event(self):
18
                e = heapq.heappop(self.queue)
19
                self._step = e[0] - self.time
20
                self.time = e[0]
21
                self.counter += 1
22
                return e[1]
23

  
24
        def elapsed_time(self):
25
                return self.time
26

  
27
        def last_event_time(self):
28
                return self.last
29

  
30
        def step(self):
31
            return self._step
32

  
33
        def processed_events(self):
34
            return self.counter
BGPpysim/util/MyUtil.py
1
from prettytable import PrettyTable
2
import numpy as np
3
import networkx as nx 
4
import random as rnd
5
import matplotlib.pyplot as plt
6

  
7
import matplotlib.colors as mcolors
8
import sys
9
import code  # code.interact(local=dict(globals(), **locals()))
10

  
11
def draw(G, pos, xmax, ymax, measures=None, saveFig=False, path=None):
12
    fig = plt.figure()
13
    lay = {k:pos[k] for k in range(0,len(pos))}
14
    if not measures:
15
        measures = nx.betweenness_centrality(G, normalized = True, weight = 'weight', endpoints=True)
16

  
17
    measure_name = "Betweenness"
18

  
19
    nodes = nx.draw_networkx_nodes(G, lay, node_size=50, cmap=plt.cm.Spectral, 
20
                                       node_color=measures.values(),
21
                                       nodelist=measures.keys())
22

  
23
    #nodes.set_norm(mcolors.SymLogNorm(linthresh=0.01, linscale=1))
24
    mes=measures.values()
25
    nodes.set_norm(mcolors.LogNorm(vmin=0.001, vmax=max(mes)))
26
    #nodes.set_norm(mcolors.LogNorm())
27

  
28
    edges = nx.draw_networkx_edges(G, lay)
29
    plt.title(measure_name)
30

  
31
    myticks=np.geomspace(start=0.001, stop=max(mes), num=7)
32
    cbar=plt.colorbar(nodes, ticks=myticks, label='Norm BC')
33
    cbar.ax.set_yticklabels(["{0:0.4f}".format(i) for i in myticks])
34
    #plt.colorbar(ticks=range(6), label='digit value')
35
    #plt.clim(-0.5, 5.5)
36
    plt.xlim(0, xmax)
37
    plt.ylim(0, ymax)
38
    plt.xticks(range(0,105,5))
39
    plt.yticks(range(0,105,5))
40
    plt.grid(which='both')
41
    if not saveFig:
42
        plt.ion()
43
        plt.draw()
44
        plt.pause(0.01)
45
        plt.clf()
46
    else:
47
        fig.savefig(path, format='pdf')
48
        #plt.clf()
49
        #plt.show()
50

  
51
def dictAlikes(d1, d2, perc):
52
	if (sorted(d1.keys()) != sorted(d2.keys())):
53
		return False
54
	for k in d1:
55
		a = float(d1[k])
56
		b = float(d2[k])
57
		if (not b - (b*perc) <= a <= b + (b*perc)):
58
			return False
59
	return True
60

  
61
def summary(v):
62
    vmin=min(v)
63
    vmax=max(v)
64
    tot=sum(v)
65
    avg=np.mean(v)
66
    std=np.std(v)
67
    t = PrettyTable(['min','max', 'mean','std','tot'])
68
    s = "%.4f %.4f %.4f %.4f %.4f" % (vmin,vmax,avg,std,tot)
69
    t.add_row(s.split())
70
    print t
71
    return avg, std, vmax, vmin, tot
BGPpysim/util/event_log.py
1
class EventLog(object):
2

  
3
    def __init__(self, time, evType, prefix, as_path):
4
        self.time = time
5
        self.evType = evType
6
        self.prefix = prefix
7
        self.as_path = as_path
8

  
9
    def to_dict(self):
10
        return self.__dict__
BGPpysim/util/fabrex1.edgelist
1
S,		T, Weight
2
SOURCE	X1	1
3
X1		X2	1
4
X1		Y1	1
5
X2		X3	1
6
X2		Y2	1
7
X3		Y3	1
8
X3		X4	1
BGPpysim/util/myqueue.py
1
class MyQueue(object):
2

  
3
    def __init__(self):
4
        self.q = []
5

  
6
    def push(self, item):
7
        self.q.append(item)
8

  
9
    def enqueue(self, item):
10
        self.q.append(item)
11

  
12
    def pop(self):
13
        return self.q.pop(0)
14

  
15
    def dequeue(self):
16
        return self.q.pop(0)
17

  
18
    def get(self, item):
19
        return self.q[0]
20

  
21
    def isEmpty(self):
22
        return not self.q
BGPpysim/util/node.py
1
from util.routing_table import RoutingTable as RT
2
from util.routing_table import Route
3
from util.myqueue import MyQueue as MyQueue
4
from collections import defaultdict
5
from prettytable import PrettyTable
6
from policy import policy
7
import json
8
import code  # code.interact(local=dict(globals(), **locals()))
9
from util.event_log import EventLog
10

  
11

  
12
class Node(object):
13

  
14
    def __init__(self, node_id, sim_dir, node_type='C', prefixes=[]):
15
        self.sim_dir = sim_dir
16
        self.ID = node_id
17
        self.nodeType = node_type
18
        self.RT = RT()
19
        self.rxQueue = MyQueue()
20
        self.neighs = defaultdict(dict)
21
        # self.policies?
22
        self.exportPrefixes = prefixes
23
        # MRAI da configurare, XdestXneigh
24
        self.events_memory = []
25
        self.configure()
26

  
27
    '''
28
    Configure ha 3 compiti:
29
    1. Far capire alla RT che sino i vicini del nodo, per poter
30
    settare gli MRAI x-VICINO, x-destinazione
31
    2. Mettere in canna i primi update da mandare, 
32
      relativi ai prefissi esportati da questo nodo.
33
      Trucco: si mettono gli exportPrefix inizialmente
34
      nella coda di ricezione
35
    3. inizializzare il file log (csv|json)?
36
    '''
37

  
38
    def configure(self):
39
        # far conoscere a RT i negihbour
40
        self.RT.set_neighbours(self.neighs)
41
        # autoricezione prefissi da esportare
42
        for prefix in self.exportPrefixes:
43
            route = Route(prefix, {'AS_PATH': ''})
44
            self_update = (self.ID, route)
45
            self.rxQueue.push(self_update)
46
        # apertura file di log
47
        self.logfile = open(self.sim_dir + "/" + self.ID + "_log.csv", 'a')
48
        self.logfile.write("TIME|EVENT_TYPE|PREFIX|AS_PATH"+'\n')
49

  
50
    def toString(self):
51
        s = PrettyTable()
52
        s.field_names = ["nID", "nTYPE", "NEIGHS", "expPREFIX"]
53
        neighPrint = {}
54
        for n in self.neighs:
55
            neighPrint[n]={}
56
            for k,v in self.neighs[n].items():
57
                if k in ['relation', 'mrai']:
58
                    neighPrint[n][k]=v
59
        s.add_row([self.ID, self.nodeType, '\n'.join(
60
            map(str, neighPrint.items())), ('\n').join(self.exportPrefixes)])
61
        print(s)
62

  
63
    def log(self, evlog):
64
        self.events_memory.append(evlog)
65
        #to_write = json.dumps(event_describer)
66
        self.logfile.write('|'.join([str(evlog.time), evlog.evType,
67
                                     evlog.prefix, evlog.as_path])+'\n')
68

  
69
        '''
70
        - route da annunciare
71
        - vicino a cui mandiamo l'annuncio
72
        '''
73

  
74
    def sendUpdate(self, route, neigh, time):
75
        #print(self.ID, ": sending Update")
76
        try:
77
            mrai = self.RT[route.prefix]['MRAIs'][neigh]
78
            if mrai <= time:  # mrai scaduto! ready2fire!
79
                self.really_send_update(route, neigh, time)
80
            else:
81
                pass  # just wait mrai to fire
82
        except KeyError:
83
            # MRAIs for the couple (prefix, neigh) not found!
84
            # assenza di MRAI per (prefix, neigh) ==> ready2fire
85
            raise Exception("\u001b[31m"+self.ID +
86
                            ": mrai not found for neigh "+neigh)
87

  
88
    def really_send_update(self, route, neigh, time):
89
        '''really send:
90
        1. mettere l'update nel bufferRX del vicino
91
        2. impostare l'MRAI per questa rotta con questo vicino
92
        3. flaggare la rotta come comunicata a questo vicino'''
93
        # 1.
94
        pyneigh = self.neighs[neigh]['pynode']
95
        rt4update = Route(route.prefix, {})
96
        rasp = route.as_path()
97
        newAS_PATH = rasp + ',' + self.ID if rasp != "" else self.ID 
98
        rt4update.attr['AS_PATH'] = newAS_PATH
99
        update = (self.ID, rt4update)
100
        pyneigh.rxQueue.push(update)
101
        # 2. and 3.
102
        #code.interact(local=dict(globals(), **locals()))
103
        self.RT[route.prefix]['MRAIs'][neigh] = time + self.neighs[neigh]['mrai']
104
        self.RT[route.prefix]['SHARED_FLAG'][neigh] = True
105

  
106
    def processRXupdates(self, time):
107
        #print(self.ID, ": processing Received Updates")
108
        while not self.rxQueue.isEmpty():
109
            update = self.rxQueue.pop()
110
            self.log(EventLog(time, 'UpdateRX',
111
                              update[1].prefix, update[1].as_path()))
112
            self.processUpdate(update, time)
113

  
114
    def processUpdate(self, update, time):
115
        sender, route = update
116
        route_preference = policy(self.ID, route)
117

  
118
        # Standard Bellman-Ford to update RT
119
        if route.prefix not in self.RT:
120
            self.RT.install_route(route, sender, route_preference, time)
121
        elif route.prefix in self.RT:
122
            current_preference = self.RT[route.prefix]['PREFERENCE']
123
            if route_preference > current_preference:
124
                self.RT.install_route(route, sender, route_preference, time)
125

  
126
        # Capire se ci sono aggiornamenti da propagare
127
        for neigh in self.neighs:
128
            myNeighIsMy = self.neighs[neigh]['relation']
129
            # vuol dire non gliela ho comunicata
130
            if self.RT[route.prefix]['SHARED_FLAG'][neigh] == False:
131
                # policy propagazione update in base a relazioni tra nodi e loro tipo...
132
                if myNeighIsMy == 'customer':
133
                    '''Da implementare anche, in futuro, la propgazione
134
                    nei seguenti casi:
135
                    - se ho imparato la rotta da un provider OR peer ==> manda ai miei customer
136
                    - se mi arriva da un customer ==> manda a tutti tranne a chi me l'ha mandata'''
137
                    self.sendUpdate(route, neigh, time)
BGPpysim/util/routing_table.py
1
from util.event_log import EventLog
2
from collections import defaultdict
3
from prettytable import PrettyTable
4
import code  # code.interact(local=dict(globals(), **locals()))
5

  
6

  
7
class Route(object):
8

  
9
    def __init__(self, prefix, attr={}):
10
        self.prefix = prefix
11
        self. attr = attr
12

  
13
    def as_path(self):
14
        return self.attr['AS_PATH']
15

  
16

  
17
class RoutingTable(object):
18

  
19
    def __init__(self):
20
        self.rt = {}
21
        self.__flag_change = False
22
        pass
23

  
24
    def __contains__(self, key):
25
        return key in self.rt
26

  
27
    def __getitem__(self, key):
28
        return self.rt[key]
29

  
30
    def __setitem__(self, key, value):
31
        self.rt[key] = value
32

  
33
    def set_neighbours(self, neighs):
34
        self.neighs = neighs
35

  
36
        '''Stiamo sicuramente aggiornando una rotta (appena imparata, o migliorata)
37
        Le cose da fare sono:
38
        - 
39
        '''
40

  
41
    def dumps(self):
42
        s = PrettyTable()
43
        s.field_names = ["PREFIX", "AS_PATH", "NH", "PREFERENCE"]
44
        for p in self.rt:
45
            s.add_row([p, self.rt[p]['AS_PATH'], self.rt[p]
46
                       ['NH'], self.rt[p]['PREFERENCE']])
47
        print(s)
48

  
49
    def install_route(self, route, sender, route_preference, time):
50
        prefix, NH, as_path, preference = route.prefix, sender, route.as_path(), route_preference
51
        new_route = route.prefix not in self.rt
52
        self.rt[prefix] = {'NH': NH, 'AS_PATH': as_path,
53
                           'PREFERENCE': preference}
54
        if new_route:
55

  
56
            self.rt[route.prefix]['MRAIs'] = defaultdict(int)
57
            self.rt[route.prefix]['SHARED_FLAG'] = defaultdict(
58
                bool)  # chiavi nuove nascono con valore False
59
            for neigh in self.neighs:
60
                # virtualmente scaduto! :)
61
                self.rt[route.prefix]['MRAIs'][neigh] = time
62
        else:
63
            # non modifico l'MRAI pre-esistente, aspetto che scada...
64
            # ma setto shared_flag = False per tutti, perchè con nessuno
65
            # ho gia condiviso la nuova rotta appena installata
66
            self.rt[route.prefix]['SHARED_FLAG'] = defaultdict(
67
                bool)  # chiavi nuove nascono con valore False
68
            self.rt[route.prefix]['PREFERENCE'] = preference
69
        #code.interact(local=dict(globals(), **locals()))

Also available in: Unified diff