f93e3727f0ef7065bac292f0d7100426faacea11
[nepi.git] / src / nepi / testbeds / ns3 / connection_metadata.py
1 # -*- coding: utf-8 -*-
2
3 from constants import TESTBED_ID
4 import functools
5 from nepi.util.constants import CONNECTION_DELAY
6 from nepi.util.tunchannel_impl import \
7     crossconnect_tunchannel_peer_init, \
8     crossconnect_tunchannel_peer_compl
9
10 ### Connection functions ####
11
12 def connect_dummy(testbed_instance, guid1, guid2):
13     pass
14
15 def connect_node_device(testbed_instance, node_guid, device_guid):
16     node = testbed_instance._elements[node_guid]
17     device = testbed_instance._elements[device_guid]
18     node.AddDevice(device)
19
20 def connect_queue_device(testbed_instance, queue_guid, device_guid):
21     queue = testbed_instance._elements[queue_guid]
22     device = testbed_instance._elements[device_guid]
23     device.SetQueue(queue)
24
25 def connect_manager_device(testbed_instance, manager_guid, device_guid):
26     manager = testbed_instance._elements[manager_guid]
27     device = testbed_instance._elements[device_guid]
28     device.SetRemoteStationManager(manager)
29
30 def connect_phy_device(testbed_instance, phy_guid, device_guid):
31     phy = testbed_instance._elements[phy_guid]
32     if hasattr(phy, "GetErrorRateModel") and phy.GetErrorRateModel() == None:
33         return CONNECTION_DELAY
34     device = testbed_instance._elements[device_guid]
35     device.SetPhy(phy)
36     phy.SetDevice(device)
37     # search for the node asociated with the device
38     node_guid = testbed_instance.get_connected(device_guid, "node", "devs")
39     if len(node_guid) == 0:
40         raise RuntimeError("Can't instantiate interface %d outside netns \
41                 node" % device_guid)
42     node = testbed_instance.elements[node_guid[0]]
43     phy.SetMobility(node)
44
45 def connect_mac_device(testbed_instance, mac_guid, device_guid):
46     mac = testbed_instance._elements[mac_guid]
47     device = testbed_instance._elements[device_guid]
48     device.SetMac(mac)
49
50 def connect_errormodel_device(testbed_instance, model_guid, device_guid):
51     model = testbed_instance._elements[model_guid]
52     device = testbed_instance._elements[device_guid]
53     device.SetReceiveErrorModel(model)
54
55 def connect_errormodel_phy(testbed_instance, err_guid, phy_guid):
56     err = testbed_instance._elements[err_guid]
57     phy = testbed_instance._elements[phy_guid]
58     phy.SetErrorRateModel(err)
59
60 def connect_channel_device(testbed_instance, channel_guid, device_guid):
61     channel = testbed_instance._elements[channel_guid]
62     device = testbed_instance._elements[device_guid]
63     device.Attach(channel)
64
65 def connect_simple_channel_device(testbed_instance, channel_guid, device_guid):
66     channel = testbed_instance._elements[channel_guid]
67     device = testbed_instance._elements[device_guid]
68     device.SetChannel(channel)
69
70 def connect_loss_channel(testbed_instance, loss_guid, channel_guid):
71     loss = testbed_instance._elements[loss_guid]
72     channel = testbed_instance._elements[channel_guid]
73     channel.SetPropagationLossModel(loss)
74
75 def connect_next_loss(testbed_instance, prev_guid, next_guid):
76     prev = testbed_instance._elements[prev_guid]
77     next = testbed_instance._elements[next_guid]
78     prev.SetNext(next)
79
80 def connect_delay_channel(testbed_instance, delay_guid, channel_guid):
81     delay = testbed_instance._elements[delay_guid]
82     channel = testbed_instance._elements[channel_guid]
83     channel.SetPropagationDelayModel(delay)
84
85 def connect_node_application(testbed_instance, node_guid, application_guid):
86     node = testbed_instance._elements[node_guid]
87     application = testbed_instance._elements[application_guid]
88     node.AddApplication(application)
89 # works for ArpL3Protocol, Ipv4L3Protocol, UdpL4Protocol, TcpL4Protocol,
90 # NscTcpL4Protocol, MobilityModel (every subclass), 
91 # RoutingProtocol (every subclass)
92
93 def connect_node_other(testbed_instance, node_guid, other_guid):
94     node = testbed_instance._elements[node_guid]
95     other = testbed_instance._elements[other_guid]
96     node.AggregateObject(other)
97
98 def connect_ss_sflow(testbed_instance, station_guid, sflow_guid):
99     ss = testbed_instance._elements[station_guid]
100     sflow = testbed_instance._elements[sflow_guid]
101     ss.AddServiceFlow(sflow)
102
103 #def connect_bs_sflow(testbed_instance, station_guid, sflow_guid):
104 #    bs = testbed_instance._elements[station_guid]
105 #    sflow = testbed_instance._elements[sflow_guid]
106 #    bs.GetServiceFlowManager().AddServiceFlow (sflow)
107
108 def connect_bstation_linksched(testbed_instance, bstation_guid, linksched_guid):
109     bstation = testbed_instance._elements[bstation_guid]
110     linksched = testbed_instance._elements[linksched_guid]
111     linksched.SetBs(bstation)
112
113 def connect_classifier_sflow(testbed_instance, classifier_guid, sflow_guid):
114     classifier = testbed_instance._elements[classifier_guid]
115     sflow = testbed_instance._elements[sflow_guid]
116     csparam = testbed_instance.ns3.CsParameters(testbed_instance.ns3.CsParameters.ADD, classifier)
117     sflow.SetConvergenceSublayerParam (csparam); 
118
119 def connect_fd(testbed_instance, fdnd_guid, cross_data):
120     def recvfd(sock, fdnd):
121         (fd, msg) = passfd.recvfd(sock)
122         # Store a reference to the endpoint to keep the socket alive
123         fdnd.SetFileDescriptor(fd)
124     
125     import threading
126     import passfd
127     import socket
128     sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
129     sock.bind("")
130     address = sock.getsockname()
131     # Set tun standard contract attributes
132     testbed_instance.set(fdnd_guid, "tun_addr", address)
133     testbed_instance.set(fdnd_guid, "tun_proto", "fd")
134     testbed_instance.set(fdnd_guid, "tun_port", 0)
135     testbed_instance.set(fdnd_guid, "tun_key", ("\xfa"*32).encode("base64").strip()) # unimportant, fds aren't encrypted
136     fdnd = testbed_instance._elements[fdnd_guid]
137     t = threading.Thread(target=recvfd, args=(sock,fdnd))
138     t.start()
139
140 def connect_tunchannel_fd(testbed_instance, tun_guid, fdnd_guid):
141     fdnd = testbed_instance._elements[fdnd_guid]
142     tun = testbed_instance._elements[tun_guid]
143
144     # Create socket pair to connect the FDND and the TunChannel with it
145     import socket
146     sock1, sock2 = socket.socketpair(
147         socket.AF_UNIX, socket.SOCK_SEQPACKET)
148
149     # Store a reference to the endpoint to keep the socket alive
150     fdnd._endpoint_socket = sock1
151     fdnd.SetFileDescriptor(sock1.fileno())
152    
153     # Send the other endpoint to the TUN channel
154     tun.tun_socket = sock2
155     
156     # With this kind of tun_socket, NS3 will expect a PI header
157     # (sockets don't support the TUNGETIFF ioctl, so it will assume
158     # the default presence of PI headers)
159     tun.with_pi = True
160
161
162 ### Connector information ###
163
164 connector_types = dict({
165     "node": dict({
166                 "help": "Connector to a ns3::Node object (mandatory)",
167                 "name": "node",
168                 "max": 1,
169                 "min": 1
170             }),
171     "devs": dict({
172                 "help": "Connector to network interfaces",
173                 "name": "devs",
174                 "max": -1,
175                 "min": 0
176             }),
177     "dev2": dict({
178                 "help": "Connector to exactly two network interfaces (mandatory)",
179                 "name": "dev2",
180                 "max": 2,
181                 "min": 2
182             }),
183     "dev": dict({
184                 "help": "Connector to exactly one network interface (mandatory)",
185                 "name": "dev",
186                 "max": 1,
187                 "min": 1
188             }),
189     "apps": dict({
190                 "help": "Connector to applications", 
191                 "name": "apps",
192                 "max": -1,
193                 "min": 0
194             }),
195     "protos": dict({
196                 "help": "Connector to network stacks and protocols", 
197                 "name": "protos",
198                 "max": -1,
199                 "min": 0
200             }),
201     "chan": dict({
202                 "help": "Connector to a channel for the device (mandatory)", 
203                 "name": "chan",
204                 "max": 1,
205                 "min": 1
206             }),
207     "queue": dict({
208                 "help": "Connector to a queueing discipline (mandatory)", 
209                 "name": "queue",
210                 "max": 1,
211                 "min": 1
212             }),
213     "err": dict({
214                 "help": "Connector to an error model for the device", 
215                 "name": "err",
216                 "max": 1,
217                 "min": 0
218             }),
219     "->fd": dict({
220                 "help": "Connector for file descriptor reception for devices with file descriptors",
221                 "name": "->fd",
222                 "max": 1,
223                 "min": 0
224             }),
225     "fd->": dict({
226                 "help": "Connector for file descriptor providing for devices with file descriptors",
227                 "name": "fd->",
228                 "max": 1,
229                 "min": 0
230             }),
231     "phy": dict({
232                 "help": "Connector to a PHY wifi model", 
233                 "name": "phy",
234                 "max": 1,
235                 "min": 0
236             }),
237     "phys": dict({
238                 "help": "Connector to a wifi channel with PHY wifi models", 
239                 "name": "phys",
240                 "max": -1,
241                 "min": 0
242             }),
243     "mac": dict({
244                 "help": "Connector to a MAC wifi model", 
245                 "name": "mac",
246                 "max": 1,
247                 "min": 0
248             }),
249     "manager": dict({
250                 "help": "Connector to a wifi manager", 
251                 "name": "manager",
252                 "max": 1,
253                 "min": 0
254             }),
255     "delay": dict({
256                 "help": "Connector to a delay model", 
257                 "name": "delay",
258                 "max": 1,
259                 "min": 0
260             }),
261     "loss": dict({
262                 "help": "Connector to a loss model", 
263                 "name": "loss",
264                 "max": 1,
265                 "min": 0
266             }),
267     "prev": dict({
268                 "help": "Connector to the previous loss model", 
269                 "name": "prev",
270                 "max": 1,
271                 "min": 0
272             }),
273     "next": dict({
274                 "help": "Connector to the next loss model", 
275                 "name": "next",
276                 "max": 1,
277                 "min": 0
278             }),
279     "mobility": dict({
280                 "help": "Connector to a mobility model", 
281                 "name": "mobility",
282                 "max": 1,
283                 "min": 0
284             }),
285     "tcp": dict({
286                 "help": "Connector for ip-ip tunneling over TCP link", 
287                 "name": "tcp",
288                 "max": 1, 
289                 "min": 0
290             }),
291     "udp": dict({
292                 "help": "Connector for ip-ip tunneling over UDP datagrams", 
293                 "name": "udp",
294                 "max": 1, 
295                 "min": 0
296             }),
297     "sflows": dict({
298                 "help": "Connector to service flows",
299                 "name": "sflows",
300                 "max": -1, 
301                 "min": 0
302             }),
303     "uplnk": dict({
304                 "help": "Connector to a uplink scheduler",
305                 "name": "uplnk",
306                 "max": 1, 
307                 "min": 0
308             }),
309     "dwnlnk": dict({
310                 "help": "Connector to a dowlink scheduler",
311                 "name": "dwnlnk",
312                 "max": 1, 
313                 "min": 0
314             }),
315     "classif": dict({
316                 "help": "Connector to a classifier recod",
317                 "name": "classif",
318                 "max": 1, 
319                 "min": 0
320             }),
321     "sflow": dict({
322                 "help": "Connector to a service flow",
323                 "name": "sflow",
324                 "max": 1, 
325                 "min": 0
326             }),
327     })
328
329 connections = [
330     dict({
331             "from": ( "ns3", "ns3::Node", "devs" ),
332             "to":   ( "ns3", "ns3::BridgeNetDevice", "node" ),
333             "init_code": connect_node_device,
334             "can_cross": False
335     }),
336     dict({
337             "from": ( "ns3", "ns3::Node", "devs" ),
338             "to":   ( "ns3", "ns3::CsmaNetDevice", "node" ),
339             "init_code": connect_node_device,
340             "can_cross": False
341     }),
342     dict({
343             "from": ( "ns3", "ns3::Node", "devs" ),
344             "to":   ( "ns3", "ns3::EmuNetDevice", "node" ),
345             "init_code": connect_node_device,
346             "can_cross": False
347     }),
348     dict({
349             "from": ( "ns3", "ns3::Node", "devs" ),
350             "to":   ( "ns3", "ns3::PointToPointNetDevice", "node" ),
351             "init_code": connect_node_device,
352             "can_cross": False
353     }),
354     dict({
355             "from": ( "ns3", "ns3::Node", "devs" ),
356             "to":   ( "ns3", "ns3::SimpleNetDevice", "node" ),
357             "init_code": connect_node_device,
358             "can_cross": False
359     }),
360     dict({
361             "from": ( "ns3", "ns3::Node", "devs" ),
362             "to":   ( "ns3", "ns3::FdNetDevice", "node" ),
363             "init_code": connect_node_device,
364             "can_cross": False
365     }),
366     dict({
367             "from": ( "ns3", "ns3::Node", "devs" ),
368             "to":   ( "ns3", "ns3::WifiNetDevice", "node" ),
369             "init_code": connect_node_device,   
370             "can_cross": False
371     }),
372     dict({
373             "from": ( "ns3", "ns3::Node", "devs" ),
374             "to":   ( "ns3", "ns3::SubscriberStationNetDevice", "node" ),
375             "init_code": connect_node_device,   
376             "can_cross": False
377     }),
378     dict({
379             "from": ( "ns3", "ns3::Node", "devs" ),
380             "to":   ( "ns3", "ns3::BaseStationNetDevice", "node" ),
381             "init_code": connect_node_device,   
382             "can_cross": False
383     }),
384     dict({
385             "from": ( "ns3", "ns3::DropTailQueue", "dev" ),
386             "to":   ( "ns3", "ns3::CsmaNetDevice", "queue" ),
387             "init_code": connect_queue_device,
388             "can_cross": False
389     }),
390     dict({
391             "from": ( "ns3", "ns3::DropTailQueue", "dev" ),
392             "to":   ( "ns3", "ns3::EmuNetDevice", "queue" ),
393             "init_code": connect_queue_device,
394             "can_cross": False
395     }),
396     dict({
397             "from": ( "ns3", "ns3::DropTailQueue", "dev" ),
398             "to":   ( "ns3", "ns3::PointToPointNetDevice", "queue" ),
399             "init_code": connect_queue_device,
400             "can_cross": False
401     }),
402     dict({
403             "from": ( "ns3", "ns3::ArfWifiManager", "dev" ),
404             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
405             "init_code": connect_manager_device,
406             "can_cross": False
407     }),
408     dict({
409             "from": ( "ns3", "ns3::ConstantRateWifiManager", "dev" ),
410             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
411             "init_code": connect_manager_device,
412             "can_cross": False
413     }),
414     dict({
415             "from": ( "ns3", "ns3::AarfcdWifiManager", "dev" ),
416             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
417             "init_code": connect_manager_device,
418             "can_cross": False
419     }),
420     dict({
421             "from": ( "ns3", "ns3::AarfWifiManager", "dev" ),
422             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
423             "init_code": connect_manager_device,
424             "can_cross": False
425     }),
426     dict({
427             "from": ( "ns3", "ns3::AmrrWifiManager", "dev" ),
428             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
429             "init_code": connect_manager_device,
430             "can_cross": False
431     }),
432     dict({
433             "from": ( "ns3", "ns3::CaraWifiManager", "dev" ),
434             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
435             "init_code": connect_manager_device,
436             "can_cross": False
437     }),
438     dict({
439             "from": ( "ns3", "ns3::IdealWifiManager", "dev" ),
440             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
441             "init_code": connect_manager_device,
442             "can_cross": False
443     }),
444     dict({
445             "from": ( "ns3", "ns3::MinstrelWifiManager", "dev" ),
446             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
447             "init_code": connect_manager_device,
448             "can_cross": False
449     }),
450     dict({
451             "from": ( "ns3", "ns3::OnoeWifiManager", "dev" ),
452             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
453             "init_code": connect_manager_device,
454             "can_cross": False
455     }),
456     dict({
457             "from": ( "ns3", "ns3::RraaWifiManager", "dev" ),
458             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
459             "init_code": connect_manager_device,
460             "can_cross": False
461     }),
462     dict({
463             "from": ( "ns3", "ns3::YansWifiPhy", "dev" ),
464             "to":   ( "ns3", "ns3::WifiNetDevice", "phy" ),  
465             "init_code": connect_phy_device,
466             "can_cross": False
467     }),
468     dict({
469             "from": ( "ns3", "ns3::SimpleOfdmWimaxPhy", "dev" ),
470             "to":   ( "ns3", "ns3::SubscriberStationNetDevice", "phy" ),  
471             "init_code": connect_phy_device,
472             "can_cross": False
473     }),
474     dict({
475             "from": ( "ns3", "ns3::SimpleOfdmWimaxPhy", "dev" ),
476             "to":   ( "ns3", "ns3::BaseStationNetDevice", "phy" ),  
477             "init_code": connect_phy_device,
478             "can_cross": False
479     }),
480     dict({
481             "from": ( "ns3", "ns3::ApWifiMac", "dev" ),
482             "to":   ( "ns3", "ns3::WifiNetDevice", "mac" ),
483             "init_code": connect_mac_device,
484             "can_cross": False
485     }),
486     dict({
487             "from": ( "ns3", "ns3::StaWifiMac", "dev" ),
488             "to":   ( "ns3", "ns3::WifiNetDevice", "mac" ),
489             "init_code": connect_mac_device,
490             "can_cross": False
491     }),
492     dict({
493             "from": ( "ns3", "ns3::RateErrorModel", "dev" ),
494             "to":   ( "ns3", "ns3::CsmaNetDevice", "err" ),
495             "init_code": connect_errormodel_device,
496             "can_cross": False
497     }),
498     dict({
499             "from": ( "ns3", "ns3::RateErrorModel", "dev" ),
500             "to":   ( "ns3", "ns3::PointToPointNetDevice", "err" ),
501             "init_code": connect_errormodel_device,
502             "can_cross": False
503     }),
504     dict({
505             "from": ( "ns3", "ns3::ListErrorModel", "dev" ),
506             "to":   ( "ns3", "ns3::CsmaNetDevice", "err" ),
507             "init_code": connect_errormodel_device,
508             "can_cross": False
509     }),
510     dict({
511             "from": ( "ns3", "ns3::ListErrorModel", "dev" ),
512             "to":   ( "ns3", "ns3::PointToPointNetDevice", "err" ),
513             "init_code": connect_errormodel_device,
514             "can_cross": False
515     }),
516     dict({
517         "from": ( "ns3", "ns3::NistErrorRateModel", "phy" ),        
518         "to":   ( "ns3", "ns3::YansWifiPhy", "err" ),
519         "init_code": connect_errormodel_phy,
520         "can_cross": False
521     }),
522     dict({
523         "from": ( "ns3", "ns3::CsmaChannel", "devs" ),
524         "to":   ( "ns3", "ns3::CsmaNetDevice", "chan" ),
525         "init_code": connect_channel_device,
526         "can_cross": False
527     }),
528     dict({
529         "from": ( "ns3", "ns3::PointToPointChannel", "dev2" ),
530         "to":   ( "ns3", "ns3::PointToPointNetDevice", "chan" ),
531         "init_code": connect_channel_device,
532         "can_cross": False
533     }),
534     dict({
535         "from": ( "ns3", "ns3::SimpleChannel", "devs" ),
536         "to":   ( "ns3", "ns3::SimpleNetDevice", "chan" ),
537         "init_code": connect_simple_channel_device,
538         "can_cross": False
539     }),
540     dict({
541         "from": ( "ns3", "ns3::SimpleOfdmWimaxChannel", "devs" ),
542         "to":   ( "ns3", "ns3::SubscriberStationNetDevice", "chan" ),
543         "init_code": connect_channel_device,
544         "can_cross": False
545     }),
546     dict({
547         "from": ( "ns3", "ns3::SimpleOfdmWimaxChannel", "devs" ),
548         "to":   ( "ns3", "ns3::BaseStationNetDevice", "chan" ),
549         "init_code": connect_channel_device,
550         "can_cross": False
551     }),
552     dict({
553         "from": ( "ns3", "ns3::YansWifiChannel", "phys" ),
554         "to":   ( "ns3", "ns3::YansWifiPhy", "chan" ),  
555         "init_code": connect_simple_channel_device,
556         "can_cross": False
557     }),
558     dict({
559         "from": ( "ns3", "ns3::YansWifiChannel", "phys" ),
560         "to":   ( "ns3", "ns3::YansWifiPhy", "chan" ),  
561         "init_code": connect_simple_channel_device,
562         "can_cross": False
563     }),
564     dict({
565         "from": ( "ns3", "ns3::LogDistancePropagationLossModel", "prev" ),
566         "to":   ( "ns3", "ns3::YansWifiChannel", "loss" ),  
567         "init_code": connect_loss_channel,
568         "can_cross": False
569     }),
570     dict({
571         "from": ( "ns3", "ns3::LogDistancePropagationLossModel", "prev" ),
572         "to":   ( "ns3", "ns3::LogDistancePropagationLossModel", "next" ),  
573         "init_code": connect_next_loss,
574         "can_cross": False
575     }),
576     dict({
577         "from": ( "ns3", "ns3::ConstantSpeedPropagationDelayModel", "chan" ),
578         "to":   ( "ns3", "ns3::YansWifiChannel", "delay" ),  
579         "init_code": connect_delay_channel,
580         "can_cross": False
581     }),
582     dict({
583         "from": ( "ns3", "ns3::Node", "apps" ),
584         "to":   ( "ns3", "ns3::OnOffApplication", "node" ),
585         "init_code": connect_node_application,
586         "can_cross": False
587     }),
588     dict({
589         "from": ( "ns3", "ns3::Node", "apps" ),
590         "to":   ( "ns3", "ns3::PacketSink", "node" ),
591         "init_code": connect_node_application,
592         "can_cross": False
593     }),
594     dict({
595         "from": ( "ns3", "ns3::Node", "apps" ),
596         "to":   ( "ns3", "ns3::UdpEchoClient", "node" ),
597         "init_code": connect_node_application,
598         "can_cross": False
599     }),
600     dict({
601         "from": ( "ns3", "ns3::Node", "apps" ),
602         "to":   ( "ns3", "ns3::UdpEchoServer", "node" ),
603         "init_code": connect_node_application,
604         "can_cross": False
605     }),
606     dict({
607         "from": ( "ns3", "ns3::Node", "apps" ),
608         "to":   ( "ns3", "ns3::UdpClient", "node" ),
609         "init_code": connect_node_application,
610         "can_cross": False
611     }),
612     dict({
613         "from": ( "ns3", "ns3::Node", "apps" ),
614         "to":   ( "ns3", "ns3::UdpServer", "node" ),
615         "init_code": connect_node_application,
616         "can_cross": False
617     }),    dict({
618         "from": ( "ns3", "ns3::Node", "apps" ),
619         "to":   ( "ns3", "ns3::V4Ping", "node" ),
620         "init_code": connect_node_application,
621         "can_cross": False
622     }),
623     dict({
624         "from": ( "ns3", "ns3::Node", "protos" ),
625         "to":   ( "ns3", "ns3::ArpL3Protocol", "node" ),
626         "init_code": connect_node_other,
627         "can_cross": False
628     }),
629     dict({
630         "from": ( "ns3", "ns3::Node", "protos" ),
631         "to":   ( "ns3", "ns3::Icmpv4L4Protocol", "node" ),
632         "init_code": connect_node_other,
633         "can_cross": False
634     }),
635     dict({
636         "from": ( "ns3", "ns3::Node", "protos" ),
637         "to":   ( "ns3", "ns3::Icmpv6L4Protocol", "node" ),
638         "init_code": connect_node_other,
639         "can_cross": False
640     }),
641     dict({
642         "from": ( "ns3", "ns3::Node", "protos" ),
643         "to":   ( "ns3", "ns3::Ipv4L3Protocol", "node" ),
644         "init_code": connect_node_other,
645         "can_cross": False
646     }),
647     dict({
648         "from": ( "ns3", "ns3::Node", "protos" ),
649         "to":   ( "ns3", "ns3::Ipv6L3Protocol", "node" ),
650         "init_code": connect_node_other,
651         "can_cross": False
652     }),
653     dict({
654         "from": ( "ns3", "ns3::Node", "protos" ),
655         "to":   ( "ns3", "ns3::UdpL4Protocol", "node" ),
656         "init_code": connect_node_other,
657         "can_cross": False
658     }),
659     dict({
660         "from": ( "ns3", "ns3::Node", "protos" ),
661         "to":   ( "ns3", "ns3::TcpL4Protocol", "node" ),
662         "init_code": connect_node_other,
663         "can_cross": False
664     }),
665     dict({
666         "from": ( "ns3", "ns3::Node", "mobility" ),
667         "to":   ( "ns3", "ns3::ConstantAccelerationMobilityModel", "node" ),
668         "init_code": connect_node_other,
669         "can_cross": False
670     }),
671     dict({
672         "from": ( "ns3", "ns3::Node", "mobility" ),
673         "to":   ( "ns3", "ns3::ConstantPositionMobilityModel", "node" ),
674         "init_code": connect_node_other,
675         "can_cross": False
676     }),
677     dict({
678         "from": ( "ns3", "ns3::Node", "mobility" ),
679         "to":   ( "ns3", "ns3::ConstantVelocityMobilityModel", "node" ),
680         "init_code": connect_node_other,
681         "can_cross": False
682     }),
683     dict({
684         "from": ( "ns3", "ns3::Node", "mobility" ),
685         "to":   ( "ns3", "ns3::HierarchicalMobilityModel", "node" ),
686         "init_code": connect_node_other,
687         "can_cross": False
688     }),
689     dict({
690         "from": ( "ns3", "ns3::Node", "mobility" ),
691         "to":   ( "ns3", "ns3::RandomDirection2dMobilityModel", "node" ),
692         "init_code": connect_node_other,
693         "can_cross": False
694     }),
695     dict({
696         "from": ( "ns3", "ns3::Node", "mobility" ),
697         "to":   ( "ns3", "ns3::RandomWalk2dMobilityModel", "node" ),
698         "init_code": connect_node_other,
699         "can_cross": False
700     }),
701     dict({
702         "from": ( "ns3", "ns3::Node", "mobility" ),
703         "to":   ( "ns3", "ns3::RandomWaypointMobilityModel", "node" ),
704         "init_code": connect_node_other,
705         "can_cross": False
706     }),
707     dict({
708         "from": ( "ns3", "ns3::Node", "mobility" ),
709         "to":   ( "ns3", "ns3::WaypointMobilityModel", "node" ),
710         "init_code": connect_node_other,
711         "can_cross": False
712     }),
713     dict({
714         "from": ( "ns3", "ns3::SubscriberStationNetDevice", "sflows" ),
715         "to":   ( "ns3", "ns3::ServiceFlow", "dev" ),
716         "init_code": connect_ss_sflow,
717         "can_cross": False
718     }),
719 #    dict({
720 #        "from": ( "ns3", "ns3::BaseStationNetDevice", "sflows" ),
721 #        "to":   ( "ns3", "ns3::ServiceFlow", "dev" ),
722 #        "init_code": connect_bs_sflow,
723 #        "can_cross": False
724 #    }),
725     dict({
726         "from": ( "ns3", "ns3::BaseStationNetDevice", "uplnk" ),
727         "to":   ( "ns3", "ns3::UplinkSchedulerSimple", "dev" ),
728         "init_code": connect_bstation_linksched,
729         "can_cross": False
730     }),
731     dict({
732         "from": ( "ns3", "ns3::BaseStationNetDevice", "uplnk" ),
733         "to":   ( "ns3", "ns3::UplinkSchedulerRtps", "dev" ),
734         "init_code": connect_bstation_linksched,
735         "can_cross": False
736     }),
737     dict({
738         "from": ( "ns3", "ns3::BaseStationNetDevice", "dwnlnk" ),
739         "to":   ( "ns3", "ns3::BSSchedulerSimple", "dev" ),
740         "init_code": connect_bstation_linksched,
741         "can_cross": False
742     }),
743     dict({
744         "from": ( "ns3", "ns3::BaseStationNetDevice", "dwnlnk" ),
745         "to":   ( "ns3", "ns3::BSSchedulerRtps", "dev" ),
746         "init_code": connect_bstation_linksched,
747         "can_cross": False
748     }),
749     dict({
750         "from": ( "ns3", "ns3::IpcsClassifierRecord", "sflow" ),
751         "to":   ( "ns3", "ns3::ServiceFlow", "classif" ),
752         "init_code": connect_classifier_sflow,
753         "can_cross": False
754     }),
755     dict({
756         "from": ( "ns3", "ns3::FdNetDevice", "->fd" ),
757         "to":   ( None, None, "fd->" ),
758         "init_code": connect_fd,
759         "can_cross": True
760     }),
761     dict({
762         "from": ( "ns3", "ns3::Nepi::TunChannel", "fd->" ),
763         "to":   ( "ns3", "ns3::FdNetDevice", "->fd" ),
764         "init_code": connect_tunchannel_fd,
765         "can_cross": False
766     }),
767     dict({
768         "from": ( "ns3", "ns3::Nepi::TunChannel", "tcp"),
769         "to":   (None, None, "tcp"),
770         "init_code": functools.partial(crossconnect_tunchannel_peer_init,"tcp"),
771         "compl_code": functools.partial(crossconnect_tunchannel_peer_compl,"tcp"),
772         "can_cross": True
773     }),
774     dict({
775         "from": ( "ns3", "ns3::Nepi::TunChannel", "udp"),
776         "to":   (None, None, "udp"),
777         "init_code": functools.partial(crossconnect_tunchannel_peer_init,"udp"),
778         "compl_code": functools.partial(crossconnect_tunchannel_peer_compl,"udp"),
779         "can_cross": True
780     }),
781 ]