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