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