fixing wimax in ns3
[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     def recvfd(sock, fdnd):
117         (fd, msg) = passfd.recvfd(sock)
118         # Store a reference to the endpoint to keep the socket alive
119         fdnd.SetFileDescriptor(fd)
120     
121     import threading
122     import passfd
123     import socket
124     sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
125     sock.bind("")
126     address = sock.getsockname()
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").strip()) # unimportant, fds aren't encrypted
132     fdnd = testbed_instance._elements[fdnd_guid]
133     t = threading.Thread(target=recvfd, args=(sock,fdnd))
134     t.start()
135
136 def connect_tunchannel_fd(testbed_instance, tun_guid, fdnd_guid):
137     fdnd = testbed_instance._elements[fdnd_guid]
138     tun = testbed_instance._elements[tun_guid]
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     # Store a reference to the endpoint to keep the socket alive
146     fdnd._endpoint_socket = sock1
147     fdnd.SetFileDescriptor(sock1.fileno())
148    
149     # Send the other endpoint to the TUN channel
150     tun.tun_socket = sock2
151     
152     # With this kind of tun_socket, NS3 will expect a PI header
153     # (sockets don't support the TUNGETIFF ioctl, so it will assume
154     # the default presence of PI headers)
155     tun.with_pi = True
156
157
158 ### Connector information ###
159
160 connector_types = dict({
161     "node": dict({
162                 "help": "Connector to a ns3::Node object (mandatory)",
163                 "name": "node",
164                 "max": 1,
165                 "min": 1
166             }),
167     "devs": dict({
168                 "help": "Connector to network interfaces",
169                 "name": "devs",
170                 "max": -1,
171                 "min": 0
172             }),
173     "dev2": dict({
174                 "help": "Connector to exactly two network interfaces (mandatory)",
175                 "name": "dev2",
176                 "max": 2,
177                 "min": 2
178             }),
179     "dev": dict({
180                 "help": "Connector to exactly one network interface (mandatory)",
181                 "name": "dev",
182                 "max": 1,
183                 "min": 1
184             }),
185     "apps": dict({
186                 "help": "Connector to applications", 
187                 "name": "apps",
188                 "max": -1,
189                 "min": 0
190             }),
191     "protos": dict({
192                 "help": "Connector to network stacks and protocols", 
193                 "name": "protos",
194                 "max": -1,
195                 "min": 0
196             }),
197     "chan": dict({
198                 "help": "Connector to a channel for the device (mandatory)", 
199                 "name": "chan",
200                 "max": 1,
201                 "min": 1
202             }),
203     "queue": dict({
204                 "help": "Connector to a queueing discipline (mandatory)", 
205                 "name": "queue",
206                 "max": 1,
207                 "min": 1
208             }),
209     "err": dict({
210                 "help": "Connector to an error model for the device", 
211                 "name": "err",
212                 "max": 1,
213                 "min": 0
214             }),
215     "->fd": dict({
216                 "help": "Connector for file descriptor reception for devices with file descriptors",
217                 "name": "->fd",
218                 "max": 1,
219                 "min": 0
220             }),
221     "fd->": dict({
222                 "help": "Connector for file descriptor providing for devices with file descriptors",
223                 "name": "fd->",
224                 "max": 1,
225                 "min": 0
226             }),
227     "phy": dict({
228                 "help": "Connector to a PHY wifi model", 
229                 "name": "phy",
230                 "max": 1,
231                 "min": 0
232             }),
233     "phys": dict({
234                 "help": "Connector to a wifi channel with PHY wifi models", 
235                 "name": "phys",
236                 "max": -1,
237                 "min": 0
238             }),
239     "mac": dict({
240                 "help": "Connector to a MAC wifi model", 
241                 "name": "mac",
242                 "max": 1,
243                 "min": 0
244             }),
245     "manager": dict({
246                 "help": "Connector to a wifi manager", 
247                 "name": "manager",
248                 "max": 1,
249                 "min": 0
250             }),
251     "delay": dict({
252                 "help": "Connector to a delay model", 
253                 "name": "delay",
254                 "max": 1,
255                 "min": 0
256             }),
257     "loss": dict({
258                 "help": "Connector to a loss model", 
259                 "name": "loss",
260                 "max": 1,
261                 "min": 0
262             }),
263     "prev": dict({
264                 "help": "Connector to the previous loss model", 
265                 "name": "prev",
266                 "max": 1,
267                 "min": 0
268             }),
269     "next": dict({
270                 "help": "Connector to the next loss model", 
271                 "name": "next",
272                 "max": 1,
273                 "min": 0
274             }),
275     "mobility": dict({
276                 "help": "Connector to a mobility model", 
277                 "name": "mobility",
278                 "max": 1,
279                 "min": 0
280             }),
281     "tcp": dict({
282                 "help": "Connector for ip-ip tunneling over TCP link", 
283                 "name": "tcp",
284                 "max": 1, 
285                 "min": 0
286             }),
287     "udp": dict({
288                 "help": "Connector for ip-ip tunneling over UDP datagrams", 
289                 "name": "udp",
290                 "max": 1, 
291                 "min": 0
292             }),
293     "sflows": dict({
294                 "help": "Connector to service flows",
295                 "name": "sflows",
296                 "max": -1, 
297                 "min": 0
298             }),
299     "uplnk": dict({
300                 "help": "Connector to a uplink scheduler",
301                 "name": "uplnk",
302                 "max": 1, 
303                 "min": 0
304             }),
305     "dwnlnk": dict({
306                 "help": "Connector to a dowlink scheduler",
307                 "name": "dwnlnk",
308                 "max": 1, 
309                 "min": 0
310             }),
311     "classif": dict({
312                 "help": "Connector to a classifier recod",
313                 "name": "classif",
314                 "max": 1, 
315                 "min": 0
316             }),
317     "sflow": dict({
318                 "help": "Connector to a service flow",
319                 "name": "sflow",
320                 "max": 1, 
321                 "min": 0
322             }),
323     })
324
325 connections = [
326     dict({
327             "from": ( "ns3", "ns3::Node", "devs" ),
328             "to":   ( "ns3", "ns3::BridgeNetDevice", "node" ),
329             "init_code": connect_node_device,
330             "can_cross": False
331     }),
332     dict({
333             "from": ( "ns3", "ns3::Node", "devs" ),
334             "to":   ( "ns3", "ns3::CsmaNetDevice", "node" ),
335             "init_code": connect_node_device,
336             "can_cross": False
337     }),
338     dict({
339             "from": ( "ns3", "ns3::Node", "devs" ),
340             "to":   ( "ns3", "ns3::EmuNetDevice", "node" ),
341             "init_code": connect_node_device,
342             "can_cross": False
343     }),
344     dict({
345             "from": ( "ns3", "ns3::Node", "devs" ),
346             "to":   ( "ns3", "ns3::PointToPointNetDevice", "node" ),
347             "init_code": connect_node_device,
348             "can_cross": False
349     }),
350     dict({
351             "from": ( "ns3", "ns3::Node", "devs" ),
352             "to":   ( "ns3", "ns3::SimpleNetDevice", "node" ),
353             "init_code": connect_node_device,
354             "can_cross": False
355     }),
356     dict({
357             "from": ( "ns3", "ns3::Node", "devs" ),
358             "to":   ( "ns3", "ns3::FdNetDevice", "node" ),
359             "init_code": connect_node_device,
360             "can_cross": False
361     }),
362     dict({
363             "from": ( "ns3", "ns3::Node", "devs" ),
364             "to":   ( "ns3", "ns3::WifiNetDevice", "node" ),
365             "init_code": connect_node_device,   
366             "can_cross": False
367     }),
368     dict({
369             "from": ( "ns3", "ns3::Node", "devs" ),
370             "to":   ( "ns3", "ns3::SubscriberStationNetDevice", "node" ),
371             "init_code": connect_node_device,   
372             "can_cross": False
373     }),
374     dict({
375             "from": ( "ns3", "ns3::Node", "devs" ),
376             "to":   ( "ns3", "ns3::BaseStationNetDevice", "node" ),
377             "init_code": connect_node_device,   
378             "can_cross": False
379     }),
380     dict({
381             "from": ( "ns3", "ns3::DropTailQueue", "dev" ),
382             "to":   ( "ns3", "ns3::CsmaNetDevice", "queue" ),
383             "init_code": connect_queue_device,
384             "can_cross": False
385     }),
386     dict({
387             "from": ( "ns3", "ns3::DropTailQueue", "dev" ),
388             "to":   ( "ns3", "ns3::EmuNetDevice", "queue" ),
389             "init_code": connect_queue_device,
390             "can_cross": False
391     }),
392     dict({
393             "from": ( "ns3", "ns3::DropTailQueue", "dev" ),
394             "to":   ( "ns3", "ns3::PointToPointNetDevice", "queue" ),
395             "init_code": connect_queue_device,
396             "can_cross": False
397     }),
398     dict({
399             "from": ( "ns3", "ns3::ArfWifiManager", "dev" ),
400             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
401             "init_code": connect_manager_device,
402             "can_cross": False
403     }),
404     dict({
405             "from": ( "ns3", "ns3::ConstantRateWifiManager", "dev" ),
406             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
407             "init_code": connect_manager_device,
408             "can_cross": False
409     }),
410     dict({
411             "from": ( "ns3", "ns3::AarfcdWifiManager", "dev" ),
412             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
413             "init_code": connect_manager_device,
414             "can_cross": False
415     }),
416     dict({
417             "from": ( "ns3", "ns3::AarfWifiManager", "dev" ),
418             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
419             "init_code": connect_manager_device,
420             "can_cross": False
421     }),
422     dict({
423             "from": ( "ns3", "ns3::AmrrWifiManager", "dev" ),
424             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
425             "init_code": connect_manager_device,
426             "can_cross": False
427     }),
428     dict({
429             "from": ( "ns3", "ns3::CaraWifiManager", "dev" ),
430             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
431             "init_code": connect_manager_device,
432             "can_cross": False
433     }),
434     dict({
435             "from": ( "ns3", "ns3::IdealWifiManager", "dev" ),
436             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
437             "init_code": connect_manager_device,
438             "can_cross": False
439     }),
440     dict({
441             "from": ( "ns3", "ns3::MinstrelWifiManager", "dev" ),
442             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
443             "init_code": connect_manager_device,
444             "can_cross": False
445     }),
446     dict({
447             "from": ( "ns3", "ns3::OnoeWifiManager", "dev" ),
448             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
449             "init_code": connect_manager_device,
450             "can_cross": False
451     }),
452     dict({
453             "from": ( "ns3", "ns3::RraaWifiManager", "dev" ),
454             "to":   ( "ns3", "ns3::WifiNetDevice", "manager" ),  
455             "init_code": connect_manager_device,
456             "can_cross": False
457     }),
458     dict({
459             "from": ( "ns3", "ns3::YansWifiPhy", "dev" ),
460             "to":   ( "ns3", "ns3::WifiNetDevice", "phy" ),  
461             "init_code": connect_phy_device,
462             "can_cross": False
463     }),
464     dict({
465             "from": ( "ns3", "ns3::SimpleOfdmWimaxPhy", "dev" ),
466             "to":   ( "ns3", "ns3::SubscriberStationNetDevice", "phy" ),  
467             "init_code": connect_phy_device,
468             "can_cross": False
469     }),
470     dict({
471             "from": ( "ns3", "ns3::SimpleOfdmWimaxPhy", "dev" ),
472             "to":   ( "ns3", "ns3::BaseStationNetDevice", "phy" ),  
473             "init_code": connect_phy_device,
474             "can_cross": False
475     }),
476     dict({
477             "from": ( "ns3", "ns3::ApWifiMac", "dev" ),
478             "to":   ( "ns3", "ns3::WifiNetDevice", "mac" ),
479             "init_code": connect_mac_device,
480             "can_cross": False
481     }),
482     dict({
483             "from": ( "ns3", "ns3::StaWifiMac", "dev" ),
484             "to":   ( "ns3", "ns3::WifiNetDevice", "mac" ),
485             "init_code": connect_mac_device,
486             "can_cross": False
487     }),
488     dict({
489             "from": ( "ns3", "ns3::RateErrorModel", "dev" ),
490             "to":   ( "ns3", "ns3::CsmaNetDevice", "err" ),
491             "init_code": connect_errormodel_device,
492             "can_cross": False
493     }),
494     dict({
495             "from": ( "ns3", "ns3::RateErrorModel", "dev" ),
496             "to":   ( "ns3", "ns3::PointToPointNetDevice", "err" ),
497             "init_code": connect_errormodel_device,
498             "can_cross": False
499     }),
500     dict({
501             "from": ( "ns3", "ns3::ListErrorModel", "dev" ),
502             "to":   ( "ns3", "ns3::CsmaNetDevice", "err" ),
503             "init_code": connect_errormodel_device,
504             "can_cross": False
505     }),
506     dict({
507             "from": ( "ns3", "ns3::ListErrorModel", "dev" ),
508             "to":   ( "ns3", "ns3::PointToPointNetDevice", "err" ),
509             "init_code": connect_errormodel_device,
510             "can_cross": False
511     }),
512     dict({
513         "from": ( "ns3", "ns3::NistErrorRateModel", "phy" ),        
514         "to":   ( "ns3", "ns3::YansWifiPhy", "err" ),
515         "init_code": connect_errormodel_phy,
516         "can_cross": False
517     }),
518     dict({
519         "from": ( "ns3", "ns3::CsmaChannel", "devs" ),
520         "to":   ( "ns3", "ns3::CsmaNetDevice", "chan" ),
521         "init_code": connect_channel_device,
522         "can_cross": False
523     }),
524     dict({
525         "from": ( "ns3", "ns3::PointToPointChannel", "dev2" ),
526         "to":   ( "ns3", "ns3::PointToPointNetDevice", "chan" ),
527         "init_code": connect_channel_device,
528         "can_cross": False
529     }),
530     dict({
531         "from": ( "ns3", "ns3::SimpleChannel", "devs" ),
532         "to":   ( "ns3", "ns3::SimpleNetDevice", "chan" ),
533         "init_code": connect_simple_channel_device,
534         "can_cross": False
535     }),
536     dict({
537         "from": ( "ns3", "ns3::SimpleOfdmWimaxChannel", "devs" ),
538         "to":   ( "ns3", "ns3::SubscriberStationNetDevice", "chan" ),
539         "init_code": connect_channel_device,
540         "can_cross": False
541     }),
542     dict({
543         "from": ( "ns3", "ns3::SimpleOfdmWimaxChannel", "devs" ),
544         "to":   ( "ns3", "ns3::BaseStationNetDevice", "chan" ),
545         "init_code": connect_channel_device,
546         "can_cross": False
547     }),
548     dict({
549         "from": ( "ns3", "ns3::YansWifiChannel", "phys" ),
550         "to":   ( "ns3", "ns3::YansWifiPhy", "chan" ),  
551         "init_code": connect_simple_channel_device,
552         "can_cross": False
553     }),
554     dict({
555         "from": ( "ns3", "ns3::YansWifiChannel", "phys" ),
556         "to":   ( "ns3", "ns3::YansWifiPhy", "chan" ),  
557         "init_code": connect_simple_channel_device,
558         "can_cross": False
559     }),
560     dict({
561         "from": ( "ns3", "ns3::LogDistancePropagationLossModel", "prev" ),
562         "to":   ( "ns3", "ns3::YansWifiChannel", "loss" ),  
563         "init_code": connect_loss_channel,
564         "can_cross": False
565     }),
566     dict({
567         "from": ( "ns3", "ns3::LogDistancePropagationLossModel", "prev" ),
568         "to":   ( "ns3", "ns3::LogDistancePropagationLossModel", "next" ),  
569         "init_code": connect_next_loss,
570         "can_cross": False
571     }),
572     dict({
573         "from": ( "ns3", "ns3::ConstantSpeedPropagationDelayModel", "chan" ),
574         "to":   ( "ns3", "ns3::YansWifiChannel", "delay" ),  
575         "init_code": connect_delay_channel,
576         "can_cross": False
577     }),
578     dict({
579         "from": ( "ns3", "ns3::Node", "apps" ),
580         "to":   ( "ns3", "ns3::OnOffApplication", "node" ),
581         "init_code": connect_node_application,
582         "can_cross": False
583     }),
584     dict({
585         "from": ( "ns3", "ns3::Node", "apps" ),
586         "to":   ( "ns3", "ns3::PacketSink", "node" ),
587         "init_code": connect_node_application,
588         "can_cross": False
589     }),
590     dict({
591         "from": ( "ns3", "ns3::Node", "apps" ),
592         "to":   ( "ns3", "ns3::UdpEchoClient", "node" ),
593         "init_code": connect_node_application,
594         "can_cross": False
595     }),
596     dict({
597         "from": ( "ns3", "ns3::Node", "apps" ),
598         "to":   ( "ns3", "ns3::UdpEchoServer", "node" ),
599         "init_code": connect_node_application,
600         "can_cross": False
601     }),
602     dict({
603         "from": ( "ns3", "ns3::Node", "apps" ),
604         "to":   ( "ns3", "ns3::UdpClient", "node" ),
605         "init_code": connect_node_application,
606         "can_cross": False
607     }),
608     dict({
609         "from": ( "ns3", "ns3::Node", "apps" ),
610         "to":   ( "ns3", "ns3::UdpServer", "node" ),
611         "init_code": connect_node_application,
612         "can_cross": False
613     }),    dict({
614         "from": ( "ns3", "ns3::Node", "apps" ),
615         "to":   ( "ns3", "ns3::V4Ping", "node" ),
616         "init_code": connect_node_application,
617         "can_cross": False
618     }),
619     dict({
620         "from": ( "ns3", "ns3::Node", "protos" ),
621         "to":   ( "ns3", "ns3::ArpL3Protocol", "node" ),
622         "init_code": connect_node_other,
623         "can_cross": False
624     }),
625     dict({
626         "from": ( "ns3", "ns3::Node", "protos" ),
627         "to":   ( "ns3", "ns3::Icmpv4L4Protocol", "node" ),
628         "init_code": connect_node_other,
629         "can_cross": False
630     }),
631     dict({
632         "from": ( "ns3", "ns3::Node", "protos" ),
633         "to":   ( "ns3", "ns3::Icmpv6L4Protocol", "node" ),
634         "init_code": connect_node_other,
635         "can_cross": False
636     }),
637     dict({
638         "from": ( "ns3", "ns3::Node", "protos" ),
639         "to":   ( "ns3", "ns3::Ipv4L3Protocol", "node" ),
640         "init_code": connect_node_other,
641         "can_cross": False
642     }),
643     dict({
644         "from": ( "ns3", "ns3::Node", "protos" ),
645         "to":   ( "ns3", "ns3::Ipv6L3Protocol", "node" ),
646         "init_code": connect_node_other,
647         "can_cross": False
648     }),
649     dict({
650         "from": ( "ns3", "ns3::Node", "protos" ),
651         "to":   ( "ns3", "ns3::UdpL4Protocol", "node" ),
652         "init_code": connect_node_other,
653         "can_cross": False
654     }),
655     dict({
656         "from": ( "ns3", "ns3::Node", "protos" ),
657         "to":   ( "ns3", "ns3::TcpL4Protocol", "node" ),
658         "init_code": connect_node_other,
659         "can_cross": False
660     }),
661     dict({
662         "from": ( "ns3", "ns3::Node", "mobility" ),
663         "to":   ( "ns3", "ns3::ConstantAccelerationMobilityModel", "node" ),
664         "init_code": connect_node_other,
665         "can_cross": False
666     }),
667     dict({
668         "from": ( "ns3", "ns3::Node", "mobility" ),
669         "to":   ( "ns3", "ns3::ConstantPositionMobilityModel", "node" ),
670         "init_code": connect_node_other,
671         "can_cross": False
672     }),
673     dict({
674         "from": ( "ns3", "ns3::Node", "mobility" ),
675         "to":   ( "ns3", "ns3::ConstantVelocityMobilityModel", "node" ),
676         "init_code": connect_node_other,
677         "can_cross": False
678     }),
679     dict({
680         "from": ( "ns3", "ns3::Node", "mobility" ),
681         "to":   ( "ns3", "ns3::HierarchicalMobilityModel", "node" ),
682         "init_code": connect_node_other,
683         "can_cross": False
684     }),
685     dict({
686         "from": ( "ns3", "ns3::Node", "mobility" ),
687         "to":   ( "ns3", "ns3::RandomDirection2dMobilityModel", "node" ),
688         "init_code": connect_node_other,
689         "can_cross": False
690     }),
691     dict({
692         "from": ( "ns3", "ns3::Node", "mobility" ),
693         "to":   ( "ns3", "ns3::RandomWalk2dMobilityModel", "node" ),
694         "init_code": connect_node_other,
695         "can_cross": False
696     }),
697     dict({
698         "from": ( "ns3", "ns3::Node", "mobility" ),
699         "to":   ( "ns3", "ns3::RandomWaypointMobilityModel", "node" ),
700         "init_code": connect_node_other,
701         "can_cross": False
702     }),
703     dict({
704         "from": ( "ns3", "ns3::Node", "mobility" ),
705         "to":   ( "ns3", "ns3::WaypointMobilityModel", "node" ),
706         "init_code": connect_node_other,
707         "can_cross": False
708     }),
709     dict({
710         "from": ( "ns3", "ns3::SubscriberStationNetDevice", "sflows" ),
711         "to":   ( "ns3", "ns3::ServiceFlow", "dev" ),
712         "init_code": connect_station_sflow,
713         "can_cross": False
714     }),
715     dict({
716         "from": ( "ns3", "ns3::BaseStationNetDevice", "sflows" ),
717         "to":   ( "ns3", "ns3::ServiceFlow", "dev" ),
718         "init_code": connect_station_sflow,
719         "can_cross": False
720     }),
721     dict({
722         "from": ( "ns3", "ns3::BaseStationNetDevice", "uplnk" ),
723         "to":   ( "ns3", "ns3::UplinkSchedulerSimple", "dev" ),
724         "init_code": connect_bstation_linksched,
725         "can_cross": False
726     }),
727     dict({
728         "from": ( "ns3", "ns3::BaseStationNetDevice", "uplnk" ),
729         "to":   ( "ns3", "ns3::UplinkSchedulerRtps", "dev" ),
730         "init_code": connect_bstation_linksched,
731         "can_cross": False
732     }),
733     dict({
734         "from": ( "ns3", "ns3::BaseStationNetDevice", "dwnlnk" ),
735         "to":   ( "ns3", "ns3::BSSchedulerSimple", "dev" ),
736         "init_code": connect_bstation_linksched,
737         "can_cross": False
738     }),
739     dict({
740         "from": ( "ns3", "ns3::BaseStationNetDevice", "dwnlnk" ),
741         "to":   ( "ns3", "ns3::BSSchedulerRtps", "dev" ),
742         "init_code": connect_bstation_linksched,
743         "can_cross": False
744     }),
745     dict({
746         "from": ( "ns3", "ns3::IpcsClassifierRecord", "sflow" ),
747         "to":   ( "ns3", "ns3::ServiceFlow", "classif" ),
748         "init_code": connect_classifier_sflow,
749         "can_cross": False
750     }),
751     dict({
752         "from": ( "ns3", "ns3::FdNetDevice", "->fd" ),
753         "to":   ( None, None, "fd->" ),
754         "init_code": connect_fd,
755         "can_cross": True
756     }),
757     dict({
758         "from": ( "ns3", "ns3::Nepi::TunChannel", "fd->" ),
759         "to":   ( "ns3", "ns3::FdNetDevice", "->fd" ),
760         "init_code": connect_tunchannel_fd,
761         "can_cross": False
762     }),
763     dict({
764         "from": ( "ns3", "ns3::Nepi::TunChannel", "tcp"),
765         "to":   (None, None, "tcp"),
766         "init_code": functools.partial(crossconnect_tunchannel_peer_init,"tcp"),
767         "compl_code": functools.partial(crossconnect_tunchannel_peer_compl,"tcp"),
768         "can_cross": True
769     }),
770     dict({
771         "from": ( "ns3", "ns3::Nepi::TunChannel", "udp"),
772         "to":   (None, None, "udp"),
773         "init_code": functools.partial(crossconnect_tunchannel_peer_init,"udp"),
774         "compl_code": functools.partial(crossconnect_tunchannel_peer_compl,"udp"),
775         "can_cross": True
776     }),
777 ]