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