Compare commits

..

190 Commits

Author SHA1 Message Date
baihe@pku.edu.cn 964d7c6ed9 feat(qsccp): Add qsccp scenario 2023-12-22 14:01:24 +00:00
suraviregmi 9665f5c9c1 update ndnsec commands
Change-Id: Ib802fd40d53e0405b9707e76dec4f2a92f9affc5
2023-11-09 20:05:26 +00:00
awlane af975e5ed5 Update dummy keychain patch to avoid potential segfaults
Under certain circumstances, use of the dummy keychain patch can cause fairly
frequent segfaults when NFD creates UDP multicast faces. These appear to have
been due to issues with using using function-local static variables in a way that
was not thread safe. After some collaboration with Alex Afanasyev regarding finding
a cause, we landed on this fix which adjusts the offending code.

Co-Authored-By: Alex Afanasyev <aa@cs.fiu.edu>
Change-Id: Iadb812cb8a3d87b83421b7fa109dd539f0c7065f
2023-10-09 17:43:55 +00:00
Davide Pesavento 273e80f1fe ci: update all actions to the latest version
Change-Id: Ib799183ea5d613b784f275213b4b2f0f97b80cb8
2023-09-20 23:28:11 -04:00
Varun Patil aed282d565 app: allow using list for command
This allows spaces in arguments

Change-Id: Icb71157eba43488028ea4f207e8009d0201c87c7
2023-09-06 15:10:33 -07:00
awlane 92bc429fe1 Add boolean parameter to NDNRoutingHelper constructor to allow for creating permanent faces.
Refs #5264

Change-Id: I6da3e777261ec978c8cff7da4d10f9661371dacf
2023-07-27 02:29:07 +00:00
awlane cb8c911f41 Allow float value for bw parameter in topology for non-integer values in megabits.
Refs #5263

Change-Id: I1c58129a474b3ec7362419c3a76863079b648b57
2023-07-24 22:55:28 +00:00
awlane 2e7b584ab5 Update dummy keychain patch for v2 namespace change
Change-Id: I8559c33fa8b02d0144b3e23c6c2d4033059e02d4
2023-06-27 08:02:20 -05:00
tylerliu 86647794f8 performance improvements
Change-Id: Ic8aaa0728a43936cd4c6e1ed590e01ba8f0fbf5a
2023-03-14 17:38:26 -07:00
dhensley6691 edd777fdfc Add an argument returnConvergenceInfo to checkConvergence which returns detailed information when convergence fails.
Adds returnConvergenceInfo as an argument to checkConvergence which returns a dictionary of nodes detailing which prefixes were missing from each node. Argument defaults to false to ensure backwards compatibility with pre-existing experiment code.

Refs: #5236
Change-Id: Ia690d50b42f849deee755098248e91a428b8af19
2022-12-13 17:22:36 +00:00
Dylan Hensley dc05e3ce90 docs: Fix broken links in README.md
The links in README.md pointed to an outdated link for the contributor guide and to AUTHORS.md instead of AUTHORS.rst

Refs: #5235
Change-Id: I380127d607b52773cc2d4c3020c9ac9950fe6f44
2022-11-20 19:25:06 -08:00
Varun Patil 047b92cf30 docker: use source install and prune image
Using source over PPA seems appropriate since MiniNDN is
used primarily for experimentation.

Other fixes:
* Let MiniNDN install mininet.
* Switch to Ubuntu 22.04
* Fix incorrect pruning of layers

Change-Id: Id5e52756929fbe3a40597c738ca81989ffb2c075
Signed-off-by: Varun Patil <varunpatil@ucla.edu>
2022-10-31 09:21:31 -07:00
Varun Patil aad8dbea87 docker: add GitHub build and push workflow
Change-Id: Ic600e91129ad81f3a41d4cc9fd9b1d45d44351c3
Signed-off-by: Varun Patil <varunpatil@ucla.edu>
2022-10-14 17:12:29 -07:00
Junxiao Shi 1e720875d2 install: fix git error and support Ubuntu 22.04
refs #5204

Change-Id: Ic6e2ce789746a18cdb8b97e5a4e8175a89ad2e8d
2022-08-01 14:53:33 -07:00
Varun Patil 63a330d317 Add static routes to NFDs in parallel
This allows setting up static routing in large
topologies in a reasonable time. Some timer values
are also reduced, seems to work fine to me

Change-Id: I112cfd216615a100db6dc18182db40ba614d83e6
2022-07-28 14:29:12 -07:00
awlane d8e6b8e508 Create helper methods for specifying face creation via topology
and changes to enable users to run NLSR in Mini-NDN-Wifi.

Refs: #5232
Change-Id: Iac8bd170f34985aa2b7ee080033a6ceaf334bd0c
2022-07-20 14:50:26 -05:00
Varun Patil c69041f603 Allow existing faces in createFace
Change-Id: I48c09c34a81822c25cbab25bff979194829e067f
2022-06-27 20:18:48 -07:00
Varun Patil 97a347fb3a Fix and move Dockerfile to this repository
Change-Id: I07039719c82d3a727b108f7875f231cd6b79493d
2022-05-24 14:33:51 -07:00
awlane 3e95ee8bd7 Fix for dummy keychain patch for ndn-cxx 8e2a6
Change-Id: I94c4e94ba70bafba8f410b4aee748529d75826d6
2022-05-23 16:24:26 -05:00
awlane a169f5702e Allow specification of working directory via constructor argument and related cleanup
Change-Id: Ifc73371c920d1d4e47b1fa04e57de5aebd2a6b40
2022-04-22 12:54:33 -08:00
awlane c32a07be3e Fix broken checks for presence of dummy keychain due to type mismatch
Refs #5200

Change-Id: I848c979c414cb802fe09359efda96c7dd29aa73d
2022-04-19 11:55:11 -08:00
awlane 49e43c39cd Update ndn-cxx dummy keychain patch for API changes
Change-Id: Ib57923ebcf1b5b00513ed50907629acfd1b56f60
2022-03-22 17:03:28 -05:00
dulalsaurab 90faa588cc Prepare 0.6.0 release
Change-Id: I3475f8a5929e0d0672f89aa0a51c25c3880fb03f
2021-12-27 18:02:05 -08:00
Alex Lane 1d3c0a8ac5 Add Nfdc functionality to enable working with FaceID rather than FaceURI exclusively
refs: #5130

Change-Id: I1b7ca1846cafdde8e959663ba53d5bd50b455b39
2021-12-19 04:23:00 +00:00
dulalsaurab 2085544799 examples: adding some basic examples
* consumer/producer
 * ndnping
 * traffic generator
 * catchunks/putchunks

Change-Id: Ie4c37f08f29a945f2fb1ce0b4d36da1bfb3edd3b
2021-12-17 09:11:56 -08:00
dulalsaurab 8c8e633d26 container: pre-built Vagrant box and docker container
Change-Id: Id49a6426f52fd3e22a94fee4607b7e2a6d0a7454
2021-12-17 01:12:03 +00:00
Junxiao Shi 48ada89a8a install: rewrite install script
* set dependency versions: PPA, git repository & commit
* separate download and build+install steps
* don't reinstall package if it's already installed

refs #4630

Change-Id: I966fac5e1633cbabf78ce20cd151a35618efc345
2021-11-04 09:02:21 -06:00
dulalsaurab 578f2ec695 Examples: incorporate latest change of NDNPing Class
Change-Id: I01d59de621992a87c082074766dc18e9a7b549a2
2021-06-17 08:58:02 -07:00
Saurab Dulal b428660d54 Revert "simple topology files with no additional parameters"
This reverts commit eef6ee890e.

Reason for revert: Topologies (http://minindn.memphis.edu/experiment.html#configuration) with no
additional parameter (e.g. hyperbolic coordinates) can't be processed by the existing script.
processTopo assumes that additional parameters exist which is not always true.

Change-Id: I8532b399de2c6f8b2a11823711b7637758dab630
2021-06-16 23:58:20 +00:00
Philipp Moll f53ab47678 ndn_routing_helper: Show status of route calculation
Change-Id: Ib38cedfed57bc8fe1397526c3d05bac6c3d80c93
2021-06-08 12:23:04 +02:00
Alex Lane 407c5f0ef3 Allow for creation of net object without topology and mixed topology fixes
refs: #5160, #5162

Change-Id: I54c2be3a9b4ee152057a8c4f1b52c9abd7b1a2a1
2021-05-14 14:48:59 -05:00
dulalsaurab 0ed7772f3f Bug fix on ndnpingclient and experiment script
Mininet host object is passed as a prefix from experiment
to ndnpingclient, string replacement operation on the
prefix fails at the client which crashes the Mini-NDN

Change-Id: I36c1f9e2e455321d8c650fd9711088b7e5ef2b22
2021-05-13 20:16:42 +00:00
Chad Cothran eef6ee890e simple topology files with no additional parameters
Change-Id: Ie121994596424249b969bb3af94c81d768fb0fc4
2021-03-26 11:15:27 -08:00
Alexander Lane ea2d5d6802 Add wireless simulation to redesigned Mini-NDN using Mininet-wifi.
refs: #4858

Change-Id: If9f7dd069203309c998ab2ff570a6cc8ee362434
2020-10-08 15:01:18 -05:00
Alex Lane 5dbf99dd78 Hotfix for broken code artifact in install.sh
Change-Id: I3296bff4b8e095f334958d1734f15c42f03c7105
2020-10-01 17:10:48 -05:00
Saurab Dulal 576a419ef2 Prepare 0.5.0 release
Small fix to properly handle ndnsec identity check message and also update copyright years in several files.

Change-Id: I1fae8749f7d755f4af1ccca519c236480ff3f824
2020-09-16 16:35:36 +00:00
Alex Lane 587b78ff64 Add a script to generate up-to-date NDN testbed topologies for Mini-NDN
Change-Id: I9686c65fe2f38fbc980c5fb54d876ebb3d9e7ede
2020-09-14 16:05:48 -05:00
Italo Valcy ccd85b1cf1 Change workDir and resultDir to be class attribute
Change-Id: Ia52c273492195163afb3ad14f92bcf06eaee075a
2020-09-04 12:41:16 -07:00
Alex Lane 722dcd53bd patches: updates dummy keychain patch for v2 namespace changes and ndn-cxx changes
Change-Id: I43a1d4a092190a953945cf43ea5f57556a325a9c
2020-08-28 16:06:35 -05:00
phmoll 9efd73922b BUGFIX IP-Routing helper did not work for large topologies
The initial version of the IP routing helper had issues with larger
topologies, especially when multiple paths between nodes are possible.
This fix ensures, that the same route between two nodes are
installed in both directions. This leads to a 100% reachability of nodes
in larger scenarios.

Change-Id: I6165caf11e61dd948320139752c271d8cf063b2a
2020-08-26 08:24:15 -07:00
Laqin Fan cf8e7541ab Check NDN security in Minindn class before printing related info.
refs: #5125

Change-Id: I6f8c154dcce0dd1285f26a244945aff0041f5d11
2020-08-25 01:01:15 -05:00
Ashlesh Gawande 76dbe6633c nfd: uncomment transport in client.conf to allow connections on /run/<node>.sock
refs: #5039

Change-Id: Id14c60ca171f80277a248cb9452c3b4d3e39ebce
2020-04-15 21:30:37 -07:00
Ashlesh Gawande f48424a4a7 patches: update dummy keychain patch to compile against latest ndn-cxx
Change-Id: I1cf323b9550707df0e9662f527348965649c1d94
2020-04-04 17:07:28 -07:00
Giovanni Grieco bb31ed2fcd install.sh: quiet apt install for Vagrant
Vagrant VM provisioning doesn't have any mechanism for user interaction.
For this reason, it is necessary to tell APT that we are in a
non-interactive session and any install question should be answered
automatically by its preset.

For this reason, according to issue #42 and GitHub PR #43, I propose to
add "quiet" option to install.sh. This option tells Debian-based systems
to run APT in non-interactive mode. In case of important questions
during install, we can update the preset list specified in quiet_install
subroutine.

Flag functionality can always be extended in the future to support
unexpected cases where Vagrant provision hangs due to user interaction
request by some other program.

Change-Id: Iab3ce5f9b19cd6bfcf2fa180c433fb5d5d521914
2020-03-24 12:18:22 +01:00
phmoll 1f1de1f87b Add GEANT network as mini-ndn topology
Change-Id: Ieb7e96b473436ce62c2ece6f24801c7f5b9ff4dc
2020-03-18 06:36:29 +01:00
Saurab Dulal 082e4449bb routing-helper: fix route computation bug
Route computation for link-state had a bug, neighbor's list
contained the host itself and so the computation was erroneous,
and ultimately crashing.

Change-Id: I461476eef83b73b64ae943f6f08bf576e3719b94
2020-03-17 21:30:14 -05:00
Philipp Moll 55e2dd9087 Add MiniNDN utility application for PCAP logging
Change-Id: I4f8ee5b6b970c7b74e3697af4a08b72d2169dc2a
2020-03-05 21:47:42 -08:00
phmoll 52223f7144 ndn_routing_helper: fix overwriting of existing prefixes
Instead of overwriting the existing prefixes, the prefixes given
in `prefix` are now appended to the list of already existing
prefixes.

Change-Id: I300f72ab8b0d2688a3379f295499a6ffdcbb54a4
2020-03-05 21:37:49 -08:00
phmoll ad8d37e89d Move logfiles to resultDir after evaluation finished
Reimplement the behavior that copies log files to the
`resultDir`, which was most likely lost when restructuring
MiniNDN. Parts of the patch are reused from an old
MiniNDN revision.

Change-Id: I3045237950320d1eb7840af9828459e47f6d9884
2020-03-04 08:42:27 +01:00
dulalsaurab 5c79db0aec Check duplicate HR coordinates in topology file
refs: #4812
Change-Id: If6c88d24d74e8d5d0d5e815eef1270fafe7b51e6
2020-02-27 06:10:13 +00:00
Eric Newberry a95b681d95 docs: restructure and update AUTHORS.md
refs #5078

Change-Id: Ieae783cb94a482b2ec25be895f4ca3939cc190d3
2020-02-05 19:40:44 -08:00
Ashlesh Gawande 6c86e30f63 **breaking** mini-ndn: re-design
refs: #5062

Everything is now done through examples like Mininet.
bin/minindn no longer provided as a binary installed in the system
bin/minindnedit GUI: will no longer be maintained
Remove cluster edition, will be re-introduced later

Change-Id: Id4ef137cb2a04d1b0dd24d01941757363bbf7d26
2019-12-05 15:13:01 -06:00
Saurab Dulal 8ae870a591 ndn/apps: add global routing helper
Change-Id: Id2bfb035424e2214d3dad1d00da95a0715c716c9
2019-11-25 13:51:04 -06:00
Philipp Moll 61a2be8726 Add RoutingHelper to allow IP communication in experiments
Change-Id: I267e264b2583909a47229279076655a8080ace22
2019-09-20 20:15:55 +02:00
dulalsaurab 0dcdb32992 Check duplicate HR coordinates in topology file
refs: #4812

Change-Id: I8b416e7fe5d5af73957e74b030e52897b7c75a9d
2019-07-26 12:05:49 -05:00
dulalsaurab 658c78b15f nlsr: rename seq-dir to state-dir
refs: #4835

Change-Id: I4110119758f142693c34005ed838adf411374779
2019-02-06 11:20:20 -06:00
Ashlesh Gawande 6651a74f37 ndn/experiments: add tests for psync
refs: #4670

Change-Id: I4c4ac9960eb5411ced1db855e641471c7251a046
2019-01-18 16:12:39 -06:00
dulalsaurab 50778df223 fix route expiration time
Change-Id: I6de07202c58d828d3564e6be3efe545ef912840f
2018-12-20 15:10:03 -06:00
Ashlesh Gawande 2b7acee13a install.sh: install PSync
refs: #4789

Change-Id: I5ef76acec0fa8d1d48c9c473c061c0c03420d4be
2018-12-14 15:15:48 -06:00
Ashlesh Gawande 27b5e1bf84 Add startup experiments for NLSR and current testbed topology
refs: #4785

Change-Id: I957b8c229ed0696b2f3fca9445f9f27274b0e197
2018-12-10 13:27:36 -06:00
dulalsaurab 2b899536e9 ndn: bug fixes in nfdc and experiments
Change-Id: I8cb9b0a9e53e0319e3f18ab6a52867d406a31fd5
2018-11-08 12:43:44 -06:00
Alexander Lane 6f7a64fc75 Create a helper class to provide a wrapper around nfdc.
Refs #3491

Change-Id: I2cc7cbb480a6ca81ee32bbfee47ef060dd8c51f4
2018-08-20 13:09:12 -05:00
Alexander Lane d6c3cad602 Fix checks for running software to account for no-nlsr.
Refs: #4640

Change-Id: Ie4086856d1b9d4f50e99aae917718233156f8fb9
2018-06-19 17:03:14 -05:00
Alexander Lane 9944cf5129 Move the NDNPing wrapper method to a helper class.
Also updates GPL header for the current calendar year.

Refs: #3492

Change-Id: Ic4977c33edd0311b140e6db3688afbb182acec9e
2018-06-14 17:08:00 -05:00
Alexander Lane 052aabbc7b Check that NFD and NLSR are running in all hosts before running experiments.
Added functionality to prevent minindn from running w/o dependencies.

ref #4562

Change-Id: Ib7a8544c9a981335d05f710023fb55a7995e0864
2018-06-08 14:50:27 -05:00
Alexander Lane 517d34cf64 Parser fix to avoid infinite loop
Refs: #4627

Change-Id: I629bb76b3a1dbba4f44aac6ee258000a8d5ade7e
2018-06-08 14:06:40 -05:00
Ashlesh Gawande 670ff15691 Install bash completion for argcomplete
Update version to 0.4.0

refs: #4629, #4631

Change-Id: I2319a37fc1ba6587528c4ed2eadf727c3c0f6526
2018-06-08 12:27:54 -05:00
Alexander Lane 4fa88819c1 Allow use of NFD and NLSR PPA with Mini-NDN.
Refs: #3992

Change-Id: I329d0303bb4e03ec2296dfb7f7aa00cac3dadfbd
2018-06-06 11:57:31 -05:00
Alexander Lane 1bc9b47be9 Remove arbitrary arguments in favor of parsing arguments from experiment files.
refs: #4611

Change-Id: Ic668b58766fef8a1e537ccaacf82230b3fb50923
2018-05-24 13:26:35 -05:00
Ashlesh Gawande 212cb82889 Autocomplete command line arguments.
Use bashrc for sudo autocomplete (argcomplete issue num. 65 on GitHub).

refs: #4454

Change-Id: I4d46cba20d2f046878063e45615c9a8eab41ba5a
2018-05-23 13:01:39 -05:00
Alexander Lane e842cc204d Exit cleanly on Mininet errors.
Refs #4540

Change-Id: I7605c9740eca785e290e64e0d8a29339c92c7df2
2018-05-16 12:54:29 -05:00
Ashlesh Gawande 532302bbf2 nfd: add option to set CS size
Don't append NFD logs b/w runs
Re-factor NFD start from ndn_host.py to bin/minindn

refs: #4469, #4508

Change-Id: I43f594a3353bb92101a0281a4561999cd8406707
2018-03-29 12:31:03 -05:00
Saurab Dulal 5f8c796609 ndn: Fix name "cost" to "link-cost" in nlsr.conf file
Change-Id: I92dd8d143b359ac5c77b4be45d4f7fdc086cf69f
2018-03-09 12:57:20 -06:00
Saurab Dulal 092755eaae Change NFD log and conf file names to nfd.log, nfd.conf
refs: #4077

Change-Id: I1cc843376c24a784b7a37225df88d26568345d01
2018-01-23 08:46:46 -08:00
dmcoomes 73caa524d3 adjust to use ndn-cxx logging
refs: #4435

Change-Id: If8709c24f7bdc5503e9b0b7b46aca5c1a65a5c2a
2018-01-19 15:54:19 -06:00
Ashlesh Gawande ed557f5a29 docs: Prepare version 0.4.0 release notes
Change-Id: I7eecaa606c0ec835148cc3177d223a30b57eb70e
2018-01-10 17:34:35 -06:00
Jeff Thompson 55d2bf4503 install.sh: Added function commonClientLibraries
refs: #4141

Change-Id: Ia0c820506690bd28b4196b4d2335d02933d0bb29
2018-01-10 16:22:39 -06:00
Saurab Dulal 7b3655a52a Modified Vagrantfile to remove sudo from the installation process
Included -a option to encapsulate -emfrti to install all dependencies

Change-Id: Ief864f4c7c69a80cfc47fc1ef195a2842c11011d
refs: #4423, #4404
2018-01-04 14:54:15 -08:00
Nick Gordon 22642a39ca docs: mention the contributing guide
Change-Id: I5fa215dd471945d9d2d4da3c67de511d4784b522
refs: #4413
2017-12-23 14:19:12 -08:00
Saurab Dulal 7a6978eb52 Use the nlsr.conf file installed in the system
Use infoedit to edit nlsr.conf file

refs: #4386, #4038

Change-Id: I4ad1e1efe92b20f444f5f9346679574888a456ed
2017-12-20 18:50:35 +00:00
Ashlesh Gawande a80484e0bd Changes to adopt to latest ndn-cxx
refs: #4292, #4155

Change-Id: Ifb0d94e23cb3a4efc82246b45578b1d5fc04ac67
2017-12-07 14:36:53 -06:00
Saurab Dulal 5d9ba60f95 use infoedit to edit nfd config files
refs: #4038

Change-Id: I193f32f54c0b47f6e2c1803b0bc4cdda9056540a
2017-12-06 22:55:44 +00:00
dmcoomes 74da84ce4d check for coordinates before running hyperbolic routing
refs: #4252

Change-Id: I04a4278443f02eef29666800fb3cd22e53a5ca28
2017-11-29 14:43:47 -06:00
dmcoomes 80eeea157b change default working directory
refs: #4357

Change-Id: I76715ddb4408a7c8c556ea5c5dbdf573f6eb840e
2017-11-03 15:26:31 -07:00
dmcoomes 8fb3a545bb Provide a vagrant file
refs: 4307

Change-Id: I9cf1c8f75b65a4d16bb2f13eb95a819f3aedf80c
2017-11-03 15:09:10 -05:00
Ashlesh Gawande 501d4d6a3a Arbitrary arguments
refs: #4360

Change-Id: I1c746c3349a72d1e262b75d4a864f096a2dfc018
2017-11-03 13:17:12 -05:00
dmcoomes ad5de70d4b docs: update authors
refs: #4333

Change-Id: I1a541223da2eaacc9938b27f016f239c6b877729
2017-11-01 10:28:28 -05:00
dmcoomes a013686a11 Revise mininet installation instructions
refs: #4036

Change-Id: Id71cc450ea90abf26387b9a9d35cd40abceaa795
2017-10-26 12:38:01 -05:00
Ashlesh Gawande 2763f1978e Use SIGQUIT instead of SIGINT
refs: #3870

Change-Id: I915d9422d56a441b351bb9ab38a0c8377e1da34f
2017-10-26 12:20:46 -05:00
dmcoomes 2ef39c064e fix nlsr startup error
refs: #4309

Change-Id: I0eb7e97c183bbfdb86f0992533fa531698c04600
2017-10-20 14:09:02 -05:00
dmcoomes ecf9c5a1bc Provide option to disable NLSR
refs: #4309

Change-Id: I78774aa535f3e1c8dea51b05e070b0e8815ff938
2017-10-19 11:32:05 -05:00
dmcoomes 7adc7f7275 Provide option to run NLSR in dry-run mode
refs: #4326

Change-Id: Icd84ae1f59acadac478e8a3425e21fd02d86bdf8
2017-10-17 13:44:04 -05:00
dmcoomes 9850d65151 Update install.sh to use ldconfig for chronosync
refs: #4295

Change-Id: Id7dab8fc09063c6cf72ad96c31a9c4376c5c8788
2017-09-29 14:31:33 -05:00
Ashlesh Gawande 6a075c25ff Add experiment to test nlsrc
refs: #4216

Change-Id: I59d1c96bfa5cdedf308d8885cbb2c487994c4c5b
2017-08-09 15:48:27 -05:00
Ashlesh Gawande 02852a0161 Update install script to use fixed version of ChronoSync
Only install ping and dump from ndn-tools

refs: #4212

Change-Id: I6f4e2782c4a3b58fd4f60729c97ea031c0a375a1
2017-07-28 20:42:36 -05:00
Ashlesh Gawande ec084835ce Update install script for ChronoSync
Use specific commits of ndn-cxx and NFD

refs: #4125

Change-Id: Ie5a1a5f514337dcb6d0aced94169762ee518070f
2017-06-27 09:26:51 -07:00
Ashlesh Gawande 708fccabdc Create faces in NFD for each neighbor of NLSR
Add option to specify whether to use TCP or UDP face in nlsr.conf

refs: #4144, #4146

Change-Id: Ida40aef80bea0e5bcb7392e446aaefce0bea9b66
2017-06-26 13:43:12 -05:00
Ashlesh Gawande 59f8624201 Fix key does not exist error
refs: 4076

Change-Id: If3569c4620f04b9ef51fa912d865f27c77a42004
2017-05-05 15:22:38 -05:00
Ashlesh Gawande da475f06c4 docs: Prepare version 0.3.0 release notes
refs: #3985

Change-Id: I5172cfe96b104b6c0b8cdf769413b9223d79ed18
2017-03-03 09:49:05 -06:00
Ashlesh Gawande f6a610bd2e No need to store host names, make network name a constant
refs: #3958, #3972

Change-Id: I16e5b94174dd47913d7d93a22708fb41061a762c
2017-03-01 13:32:34 -08:00
Ashlesh Gawande 95789ccc5e update INSTALL.md, use mini-ndn name in CLI
refs: #3969, #3980

Change-Id: Idd84d70b5edfa8fb06cf5158ccca452764d77eb7
2017-03-01 11:25:30 -06:00
Ashlesh Gawande 5f47020f43 add new experiments for NLSR bot
refs: #3975

Change-Id: Iad1db7fca4c475d308d2f5c79cdd737967a986b2
2017-02-28 09:42:12 -06:00
Ashlesh Gawande 3bed483792 add missing cert installs and nlsr conf file update
refs: #3951, #3953

Change-Id: Id1264bed658324083618faa579640e50240fecdb
2017-02-09 14:52:59 -06:00
Ashlesh Gawande f5f304b9cd modification to use cluster version
Change-Id: Iaf169507577deba20d548348532a2e0b91a03249
refs: #3652
2017-01-12 15:39:07 -06:00
Ashlesh Gawande 044611d101 use argparse instead of optparse
refs: #3900

Change-Id: I6a883ef5d481aeac4d92e29249e9368d7b1dcf49
2016-12-23 12:30:01 -06:00
Ashlesh Gawande f932a18f7b use nfdc instead of nfd-status
refs: #3878

Change-Id: Ib3aad0fdb48e719031d03a3706d284d93ada5653
2016-12-19 23:45:38 -06:00
Ashlesh Gawande e144ceb8c2 set different site name for each router
Change-Id: Ic81d8d9908923dfafce777c091fc9b288ade7400
refs: #2719
2016-11-28 14:50:44 -06:00
Ashlesh Gawande 5518f71bfe Fix NLSR termination due to key does not exist error
refs: #3869

Change-Id: I12927eeef02f0311112fae02a1c885389947dde5
2016-11-28 13:06:44 -06:00
Ashlesh Gawande 0cccdb8a3a docs: Prepare version 0.2.0 release notes
Change-Id: Ie390e902d8389f8554b62a1dbbb8fdb73772263b
2016-08-18 10:10:51 -07:00
Ashlesh Gawande e626b63cd9 docs: update docs
refs: #3670

Change-Id: I4a90df1cf5b28d05fd81877bf4d51659e21b1119
2016-08-16 18:04:15 -05:00
Ashlesh Gawande 52e47e161d Do not update if minindn has already been installed before
refs: #3729

Change-Id: I4409de6f9ddc876aed20a34435c2186f6470fa20
2016-08-09 14:37:31 -07:00
Ashlesh Gawande 3807c1b64f exit gracefully on control-c and non-convergence
refs: #3672

Change-Id: I19df1a3318315b49816b3cf93c39bc95af52d0b3
2016-08-09 09:16:03 -07:00
Ashlesh Gawande c09c16da83 ndn_application: init processId and fix nfd not being killed
Change-Id: I3ec5d79f903130d0ce42fd1c2a18bd73065757e7
refs: #3671
2016-08-09 11:02:58 -05:00
Ashlesh Gawande b07ada8b5e set best-route strategy correctly
refs: #3696

Change-Id: Ia9285e7261167f511c7193b09f37023b68a39eeb
2016-08-05 14:31:35 -07:00
Vince Lehman 5d5a566f8b Add automatic NLSR security configuration
refs: #3050

Change-Id: I218f96a2cb11dd35de99c4a9eab056f0fed890aa
2016-07-26 14:58:30 -05:00
Yucheng Zhang 14aa596935 Use nfd.conf by default instead of nfd.conf.sample
Change-Id: I2b539d2082efa20be0aea62286426d2dde85be7f
refs: #3468
2016-07-19 09:55:43 -07:00
Vince Lehman bf600a4334 Add ProcessMonitor class
refs: #3641

Change-Id: I88bf88081038360170532d3c4bf11f1bc2650bda
2016-06-02 16:36:41 -05:00
Yucheng Zhang dd4c6b78e4 Launch NLSR with explicit configuration file
Change-Id: Icacb1b4f320a4aa7394f58611ba424924a4ae0c0
refs: #3039
2016-06-02 12:36:42 -08:00
Yucheng Zhang 008387d311 Update verification instructions
Change-Id: I4b078f9c1e934590bdaebc761c66bb6be7056cbf
refs: #3467
2016-04-05 17:19:56 -05:00
Vince Lehman 68b0815584 docs: Prepare version 0.1.1 release notes
Change-Id: Ie2d8546eedfac8e9e54d1fcc68122dcc3f90b1b9
2015-11-04 14:05:44 -06:00
Ashlesh Gawande 5fee776a3b Add MCN failure experiment
refs: #3272

Change-Id: I663680898bf4a0b9da21e0c408933cef6200564b
2015-11-04 11:25:32 -07:00
Ashlesh Gawande d9c9e52507 experiments: Allow pinging a percentage of nodes
refs: #3265

Change-Id: I80a37d4a8cf6ca5a25d03f1f98cdcf9394feb92f
2015-11-04 12:10:39 -06:00
Vince Lehman 0c5eb69d30 Remove debug statement from IP address assignment
Change-Id: Ie4fd78e9a60279e11913e806a0309554eb46fb0c
2015-11-03 09:37:41 -06:00
Ashlesh Gawande d829bfc385 Add results directory option
refs: #3266

Change-Id: I80b74969377753445925effb0b1c2010e0923b23
2015-10-27 08:52:56 -07:00
Vince Lehman d96eed31e8 Add failNode and recoverNode methods to Experiment class
refs: #3085

Change-Id: Ib99edc1c7a201f16c993aa0e0c4791c2eea15a35
2015-10-23 14:19:14 -07:00
Vince Lehman c64dcb8366 Remove "FIB Entries" from NDN host options
refs: #2912

Change-Id: I4474c7c0aad3b4c6066f096c78934f561a2bf070
2015-10-22 15:22:02 -07:00
Vince Lehman fbd47c9ef8 Add support for switches in GUI and configuration file
refs: #2583

Change-Id: I051dfe7c9e5fae292a7ca97f26f41dfc403241b8
2015-10-22 13:50:16 -05:00
Ashlesh Gawande 1b66369d43 Add working directory option
refs: #3266

Change-Id: Ifd953b242c99f75c68eb3c63ef5e51ef46195b8b
2015-10-22 11:55:30 -05:00
Vince Lehman 194be2465a Refactor program options into POD
refs: #3269

Change-Id: Ica3a302bdc74ac13aa214f589bf7dc68fcd5f262
2015-10-22 11:09:50 -05:00
Vince Lehman 498625bb71 Use nfd.conf.sample from currently installed NFD
refs: #3282

Change-Id: Idc3a70fc62b98c72970eab41d16eb587a16efe9a
2015-10-21 15:07:43 -07:00
Ashlesh Gawande 4e545d967b exit before starting up if exp name is invalid
refs: #3115

Change-Id: I901ac7b951bc21ba8069b5b9be2a1d067ba8e61b
2015-10-21 16:00:50 -05:00
Ashlesh Gawande 1cebdfc7fb experiments: Restart pings for CSU after recovery
refs: #3086

Change-Id: I54fe2a2d1b4b6cd4d09ff72b79fbb30de50d5a89
2015-10-15 10:53:52 -05:00
Ashlesh Gawande 37bffa9ceb docs: Connect Mini-NDN to external network
refs: #3052

Change-Id: I0bb060fc1095946b8f6302880aa78b817a9c07f7
2015-10-14 14:13:57 -07:00
Vince Lehman 4e7df5ad86 docs: Add mailing list to README
Change-Id: I3961b279b871d57f103aafb1921b266e5dd8aaf9
2015-07-21 11:55:49 -05:00
Vince Lehman e9f116d781 docs: Prepare version 0.1.0 release notes
Change-Id: If3a00751ed5aef36b76c2af653f0fe7b71fc7efd
2015-07-15 11:02:00 -07:00
Vince Lehman 673b013984 docs: Update AUTHORS.md
Change-Id: I69d40a72001a064e4e0cf3f248d58928ba91fdd1
2015-07-15 11:39:40 -05:00
Vince Lehman 608a1337ec Update README.md
Change-Id: I58d3a56ae8dd7bc9b24a2e219b04fabc04902868
2015-07-14 16:42:34 -07:00
Vince Lehman d1ee56a16a docs: Add GUI.md
Change-Id: Ic7ffb8dea4521af95cb87e578be3eb46af6e8f6e
2015-07-14 16:41:43 -07:00
Vince Lehman d367dbb032 docs: Add GETTING-STARTED.md
Change-Id: I43d9b3d017d9c7f62d658f93bef97a62e43aeed0
2015-07-14 16:41:22 -07:00
Vince Lehman ce7f4e9236 docs: Add EXPERIMENTS.md
refs: #2916

Change-Id: I096269b0befb086add38d1d9e9cf1aad17e4d388
2015-07-14 16:40:01 -07:00
Ashlesh Gawande 3a1b6e54e4 docs: Add CONFIG.md
Change-Id: I02272d8a6bf6f4a4eceefc9c2b8b36003e3e78c2
2015-07-14 16:39:14 -07:00
Vince Lehman b8b1806546 Add license and copyright notices
Change-Id: I47244d7e3015c7d8a4c57f4ee1cc9679bc320d43
2015-07-14 16:36:22 -07:00
Vince Lehman 1c0e097ccf Add AUTHORS.md
Change-Id: Id408542f4318c0d0b6b29725dbe61185b9194777
2015-07-14 16:04:14 -07:00
Ashlesh Gawande ab087daa66 Load topology from saved files
refs: #2911

Change-Id: Ic5b0c0713333579fd6e92c738784b3de1dda6a1d
2015-07-14 09:53:44 -05:00
Ashlesh Gawande 557cb8466a Add ability to specify multiple apps to run on each node
refs: #2933

Change-Id: Ic5d47bb3e9ab830f01b55be37848aa680174cf32
2015-07-14 09:31:10 -05:00
Ashlesh Gawande 792c6aa970 Add NdnApplication class to handle start and stop
refs: #2909

Change-Id: Ibe5760b155e0edf2227d2d7146f8b6552149a63b
2015-07-13 22:33:29 -05:00
Ashlesh Gawande 3a4afb19d5 Set NFD logging level from GUI
refs: #2913

Change-Id: I4255b0467ef8ee6c4a2803ed078256cac9fbfd9c
2015-07-13 20:28:47 -05:00
Vince Lehman 3b8bc652d4 Implement ExperimentManager
refs: #2852

Change-Id: I49b50989477914ae4b076d6d39ca661f50fc92aa
2015-07-10 16:08:18 -05:00
Ashlesh Gawande c3ed2b9960 Set NLSR logging level from GUI
refs: #2914

Change-Id: I8dca010011bbe6b94ac986ce14c6c735d8bacb17
2015-07-09 11:10:02 -05:00
Ashlesh Gawande 20f70762b6 Use default topology when no topology file is provided
Change-Id: Icbc434a82cc147c84680c77e2f089f20d50ad803
refs: #2915
2015-07-09 09:26:29 -05:00
Ashlesh Gawande 1a0129681a Remove unused files and folders
Change-Id: I5b1872651bcaff603816b83ab23464b4808cbd19
refs: #2908
2015-07-01 17:01:00 -05:00
ashu 2ad32e2a61 Using latest version of mininet
refs: #2851

Change-Id: Ica4936cb98245a0b1a22d8ceada4e7a0f6dbddc8
2015-06-16 16:02:05 -05:00
Vince Lehman cb20c547af experiment: Add multiple failure experiment
Change-Id: Ia7e856606ec483f0bb63840a0e40399058e5b6ac
2015-05-13 09:52:46 -05:00
ashu 8bf379eaf3 Update INSTALL readme
refs: #2784

Change-Id: I26b03c297da3df9d8515766d262cf3f984fbea21
2015-05-08 13:47:13 -07:00
Vince Lehman c264d44357 Update nlsr.conf for NLSR 0.2.0
Change-Id: Ic7f026858ad0ab55bd2e821ddb9c4839cbb77a00
2015-05-01 12:46:16 -07:00
ashu 7b6ba18c7e ndn: Add GUI
Change-Id: I7336bbb04121166d064b76cbad9f760c3dd16c2d
2015-05-01 13:37:45 -05:00
ashu 34c3ee0b6a ndn: Add NLSR experiments
Change-Id: I0b86b121a5c8bf6a6e6e8df5027fe49561a9283b
2015-04-16 17:24:58 -05:00
ashu 4c85880a01 Modify README
Change-Id: I18a2cdd6d9a19ae7b8cf299e11595b6182c4eaa6
2015-04-15 13:33:44 -07:00
ashu 01b62f7c46 Add ndn_utils and modify install script
refs: #2528

Change-Id: I7c26df7c91572f8e48b23ca3cddcec1b8f0216a5
2015-03-25 11:25:52 -05:00
ashu ef3490b052 ndn: Add NFD and NLSR class abstractions
refs: #2528

Change-Id: I3241af0e85f4eec4eb640aca274ff9ca4f812656
2015-03-09 14:31:23 -05:00
Caio 188d2f3940 All done! GUI + working version. Some few adjustments on the code to be done. 2015-01-22 23:35:08 -02:00
Caio 6bdcecfbfc Minor code change 2015-01-19 18:50:13 -02:00
Caio 24c0cbddbf GUI OK - ToDo: ImportTOPO 2015-01-19 18:45:53 -02:00
Caio ac585d8778 Merge pull request #11 from caio92/master
Enhancements made in MiniccnxEdit.
2014-12-01 16:41:38 -02:00
Caio Elias 2fa082da91 Small about/credits changes 2014-12-01 16:38:04 -02:00
Caio Elias e904f533e3 Updated MiniCCNxEdit, now it has the possibility to Save and Load topologies. TODO: change nodes and links parameters from the GUI 2014-12-01 16:19:22 -02:00
Caio Elias 47b243c59d First changes into new version of mnccnxedit GUI 2014-11-23 19:25:34 -02:00
Caio d8711c8d1d Merge pull request #9 from caio92/master
fixed config_parser.py
2014-10-01 00:59:36 -03:00
Caio Elias b5e55fa658 Fixed indentation in conf_parser.py 2014-09-19 14:27:54 -03:00
Caio Elias c6b56036cf Fixed small bug in conf_parser.py file that would return an error in case there was an empty line in [link] session or an empty-options host in [nodes] section of the .config file 2014-09-19 14:12:48 -03:00
Christian Esteve Rothenberg 21d9179ac0 Update README.md 2014-01-11 12:09:26 -02:00
carlosmscabral 7736b82f92 mem 2013-07-21 14:40:31 -03:00
carlosmscabral 652bad492c new gui 2013-07-18 13:23:29 -03:00
carlosmscabral 3d060fc824 3 2013-07-18 13:18:09 -03:00
carlosmscabral ceef99c108 adapt 2013-07-18 11:18:02 -03:00
carlosmscabral b9d85b724e adaptions 2013-07-15 15:24:33 -03:00
carlosmscabral b4430fb7b6 Removing debug print 2013-03-23 12:06:00 -03:00
carlosmscabral 6d3dd60010 Adding NDN testbed 2013-03-23 11:12:34 -03:00
carlosmscabral d7ccfd9f52 Right wiki Link 2013-02-25 18:18:25 -03:00
carlosmscabral e3c810e23f README 2013-02-25 18:15:40 -03:00
carlosmscabral f8ccd38513 INSTALL docs 2013-02-25 18:14:27 -03:00
carlosmscabral e121a7b55b New functions 2013-02-18 18:14:53 -03:00
carlosmscabral cd5073b5e5 install.sh correction 2013-02-04 12:38:20 -02:00
carlosmscabral 4cf72ea2ef Install/README changes 2013-02-04 12:33:50 -02:00
carlosmscabral 9ab2f8dd86 Changed Makefile and setup.py 2013-02-04 12:28:14 -02:00
carlosmscabral fc8a032ed2 - 2013-02-04 12:10:16 -02:00
carlosmscabral 29432250ec Included CPULimitedCCNHost parsing 2013-02-04 11:54:16 -02:00
carlosmscabral b2d76332dc 3 2013-02-01 19:13:23 -02:00
carlosmscabral f40ecd179c First commit 2013-02-01 18:15:58 -02:00
carlosmscabral 0fb51cc605 first commit 2013-01-12 18:02:46 -02:00
197 changed files with 8773 additions and 14312 deletions
+1
View File
@@ -0,0 +1 @@
Dockerfile
-1
View File
@@ -1 +0,0 @@
*.py diff=python
+44
View File
@@ -0,0 +1,44 @@
name: Publish Docker image
on:
push:
branches:
- master
workflow_dispatch:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Login to ${{ env.REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
pull: true
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
+18 -11
View File
@@ -1,14 +1,21 @@
mnexec
*.pyc
*~
*.1
*.xcodeproj
*.xcworkspace
\#*\#
mininet.egg-info
# Python
build
dist
doc/html
doc/latex
trunk
Mini_NDN.egg-info
*.pyc
# Docs
docs/html
docs/latex
docs/_build
# Misc
.DS_Store
dl
*.apconf
# Vagrant
.vagrant
venv/
.vscode
-297
View File
@@ -1,297 +0,0 @@
# lint Python modules using external checkers.
#
# This is the main checker controlling the other ones and the reports
# generation. It is itself both a raw checker and an astng checker in order
# to:
# * handle message activation / deactivation at the module level
# * handle some basic but necessary stats'data (number of classes, methods...)
#
[MASTER]
# Specify a configuration file.
#rcfile=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
#init-hook=
# Profiled execution.
profile=no
# Add <file or directory> to the black list. It should be a base name, not a
# path. You may set this option multiple times.
ignore=CVS
# Pickle collected data for later comparisons.
persistent=yes
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
[MESSAGES CONTROL]
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time.
#enable=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once).
disable=W0704,C0103,W0231,E1102,W0511,W0142,R0902,R0903,R0904,R0913,R0914,R0801,I0011
[REPORTS]
# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html
output-format=colorized
# Include message's id in outpu
include-ids=yes
# Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]".
files-output=no
# Tells wether to display a full report or only the messages
reports=no
# Python expression which should return a note less than 10 (10 is the highes
# note). You have access to the variables errors warning, statement which
# respectivly contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation repor
# (R0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# Add a comment according to your evaluation note. This is used by the global
# evaluation report (R0004).
comment=no
# Enable the report(s) with the given id(s).
#enable-report=
# Disable the report(s) with the given id(s).
#disable-report=
# checks for :
# * doc strings
# * modules / classes / functions / methods / arguments / variables name
# * number of arguments, local variables, branchs, returns and statements in
# functions, methods
# * required module attributes
# * dangerous default values as arguments
# * redefinition of function / method / class
# * uses of the global statemen
#
[BASIC]
# Required attributes for module, separated by a comma
required-attributes=
# Regular expression which should only match functions or classes name which do
# not require a docstring
no-docstring-rgx=__.*__
# Regular expression which should only match correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Regular expression which should only match correct module level names
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Regular expression which should only match correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$
# Regular expression which should only match correct function names
function-rgx=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match correct method names
method-rgx=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match correct instance attribute names
attr-rgx=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match correct argument names
argument-rgx=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match correct variable names
variable-rgx=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match correct list comprehension /
# generator expression variable names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_
# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata
# List of builtins function names that should not be used, separated by a comma
bad-functions=map,filter,apply,inpu
# try to find bugs in the code using type inference
#
[TYPECHECK]
# Tells wether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# List of classes names for which member attributes should not be checked
# (useful for classes with attributes dynamicaly set).
ignored-classes=SQLObjec
# When zope mode is activated, add a predefined set of Zope acquired attributes
# to generated-members.
zope=no
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E0201 when accessed.
generated-members=REQUEST,acl_users,aq_paren
# checks for
# * unused variables / imports
# * undefined variables
# * redefinition of variable from builtins or from an outer scope
# * use of variable before assigmen
#
[VARIABLES]
# Tells wether we should check for unused import in __init__ files.
init-import=no
# A regular expression matching names used for dummy variables (i.e. not used).
dummy-variables-rgx=_|dummy
# List of additional names supposed to be defined in builtins. Remember tha
# you should avoid to define new builtins when possible.
additional-builtins=
# checks for :
# * methods without self as first argumen
# * overridden methods signature
# * access only to existant members via self
# * attributes not defined in the __init__ method
# * supported interfaces implementation
# * unreachable code
#
[CLASSES]
# List of interface methods to ignore, separated by a comma. This is used for
# instance to not check methods defines in Zope's Interface base class.
ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,setUp
# checks for sign of poor/misdesign:
# * number of methods, attributes, local variables...
# * size, complexity of functions, methods
#
[DESIGN]
# Maximum number of arguments for function / method
max-args=5
# Maximum number of locals for function / method body
max-locals=15
# Maximum number of return / yield for function / method body
max-returns=6
# Maximum number of branch for function / method body
max-branchs=12
# Maximum number of statements in function / method body
max-statements=50
# Maximum number of parents for a class (see R0901).
max-parents=7
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
# Maximum number of public methods for a class (see R0904).
max-public-methods=20
# checks for
# * external modules dependencies
# * relative / wildcard imports
# * cyclic imports
# * uses of deprecated modules
#
[IMPORTS]
# Deprecated modules which should not be used, separated by a comma
deprecated-modules=regsub,string,TERMIOS,Bastion,rexec
# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report R0402 must not be disabled)
import-graph=
# Create a graph of external dependencies in the given file (report R0402 mus
# not be disabled)
ext-import-graph=
# Create a graph of internal dependencies in the given file (report R0402 mus
# not be disabled)
int-import-graph=
# checks for :
# * unauthorized constructions
# * strict indentation
# * line length
# * use of <> instead of !=
#
[FORMAT]
# Maximum number of characters on a single line.
max-line-length=80
# Maximum number of lines in a module
max-module-lines=1500
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
# checks for:
# * warning notes in the code like FIXME, XXX
# * PEP 263: source code with non ascii character but no encoding declaration
#
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO
# checks for similarities and duplicated code. This computation may be
# memory / CPU intensive, so you should disable it if you experiments some
# problems.
#
[SIMILARITIES]
# Minimum lines number of a similarity.
min-similarity-lines=4
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
+38
View File
@@ -0,0 +1,38 @@
Mini-NDN Authors
=================
The following lists maintainers, primary developers, and all much-appreciated contributors to Mini-NDN in alphabetic order.
The specific contributions of individual authors can be obtained from the git history of the [official Mini-NDN repository](https://github.com/named-data/mini-ndn).
If you would like to become a contributor to the official repository, please follow the recommendations in https://github.com/named-data/.github/blob/master/CONTRIBUTING.md.
* Alexander Afanasyev <https://users.cs.fiu.edu/~afanasyev>
* Muktadir R. Chowdhury <https://github.com/alvyC>
* Damian Coomes <https://github.com/dmcoomes>
* ***(Maintainer)*** Saurab Dulal <https://dulalsaurab.github.io>
* Laqin Fan <https://github.com/laqinfan>
* ***(Former Maintainer)*** Ashlesh Gawande <https://www.linkedin.com/in/agawande>
* Nicholas Gordon <https://github.com/gorgonical>
* Giovanni Grieco <https://github.com/GiovanniGrieco>
* ***(Maintainer)*** Alexander Lane <https://github.com/awlane>
* Vince Lehman <http://vslehman.com>
* Philipp Moll <https://github.com/phylib>
* Eric Newberry <https://ericnewberry.com>
* Junxiao Shi <https://cs.arizona.edu/~shijunxiao>
* Jeff Thompson <https://remap.ucla.edu/jeff-thompson>
* Yucheng Zhang <https://peterskycloud.wixsite.com/yzportfolio>
* Italo Valcy S Brito <https://github.com/italovalcy>
Technical Advisors
-------------------
* Lan Wang <http://www.cs.memphis.edu/~lanwang>
* Beichuan Zhang <http://cs.arizona.edu/~bzhang>
The Mini-CCNx team
-------------------
* Carlos Cabral <https://github.com/carlosmscabral>
* Caio de Moraes Elias <https://github.com/ocaio>
* Christian Esteve Rothenberg <http://www.dca.fee.unicamp.br/~chesteve>
-39
View File
@@ -1,39 +0,0 @@
Mininet Contributors
Mininet is an open source project and we gratefully acknowledge
the many contributions to the project! If you have contributed
code into the project and are not on this list, please let us know
or send a pull request.
Contributors include:
Mininet Core Team
Bob Lantz
Brandon Heller
Nikhil Handigol
Vimal Jeyakumar
Brian O'Connor
Additional Mininet Contributors
Gustavo Pantuza Coelho Pinto
Ryan Cox
Shaun Crampton
David Erickson
Glen Gibb
Andrew Ferguson
Eder Leao Fernandes
Vitaly Ivanov
Rich Lane
Murphy McCauley
José Pedro Oliveira
James Page
Angad Singh
Piyush Srivastava
Ed Swierk
Isaku Yamahata
Thanks also to everyone who has submitted issues and pull
requests on github, and to our friendly mininet-discuss
mailing list!
+674
View File
@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+37
View File
@@ -0,0 +1,37 @@
# Setup container with Ubuntu 22.04 image
FROM ubuntu:22.04
# Set the working directory to /
WORKDIR /
# expose ports for openvswitch-switch
EXPOSE 6633 6653 6640
# Update container image
RUN apt-get update -y && \
apt-get install --no-install-recommends -y \
lsb-release sudo \
zip unzip wget git ca-certificates \
curl iproute2 iputils-ping net-tools \
python3 python3-pip \
tcpdump vim x11-xserver-utils xterm && \
update-ca-certificates && \
rm -rf /var/lib/apt/lists/* && \
alias python=python3
COPY . /mini-ndn
RUN cd mini-ndn && \
pip3 install -r requirements.txt && \
./install.sh -y --source && \
cd dl/mininet && make install && cd ../.. && \
cd dl/mininet-wifi && make install && cd ../.. && \
rm -rf dl && rm -rf /var/lib/apt/lists/* && cd /
COPY docker/ENTRYPOINT.sh /
RUN chmod +x ENTRYPOINT.sh
# Change the working directory to /mini-ndn
WORKDIR /mini-ndn
ENTRYPOINT ["/ENTRYPOINT.sh"]
-166
View File
@@ -1,166 +0,0 @@
Mininet Installation/Configuration Notes
----------------------------------------
Mininet 2.1.0p1
---
The supported installation methods for Mininet are 1) using a
pre-built VM image, and 2) native installation on Ubuntu. You can also
easily create your own Mininet VM image (4).
(Other distributions may be supported in the future - if you would
like to contribute an installation script, we would welcome it!)
1. Easiest "installation" - use our pre-built VM image!
The easiest way to get Mininet running is to start with one of our
pre-built virtual machine images from <http://mininet.org/>
Boot up the VM image, log in, and follow the instructions on the
Mininet web site.
One advantage of using the VM image is that it doesn't mess with
your native OS installation or damage it in any way.
Although a single Mininet instance can simulate multiple networks
with multiple controllers, only one Mininet instance may currently
be run at a time, and Mininet requires root access in the machine
it's running on. Therefore, if you have a multiuser system, you
may wish to consider running Mininet in a VM.
2. Next-easiest option: use our Ubuntu package!
To install Mininet itself (i.e. `mn` and the Python API) on Ubuntu
12.10+:
sudo apt-get install mininet
Note: if you are upgrading from an older version of Mininet, make
sure you remove the old OVS from `/usr/local`:
sudo rm /usr/local/bin/ovs*
sudo rm /usr/local/sbin/ovs*
3. Native installation from source
3.1. Native installation from source on Ubuntu 12.04+
If you're reading this, you've probably already done so, but the
command to download the Mininet source code is:
git clone git://github.com/mininet/mininet.git
If you are running Ubuntu, you may be able to use our handy
`install.sh` script, which is in `mininet/util`.
*WARNING: USE AT YOUR OWN RISK!*
`install.sh` is a bit intrusive and may possibly damage your OS
and/or home directory, by creating/modifying several directories
such as `mininet`, `openflow`, `oftest`, `pox`, etc..
Although we hope it won't do anything completely terrible, you may
want to look at the script before you run it, and you should make
sure your system and home directory are backed up just in case!
To install Mininet itself, the OpenFlow reference implementation, and
Open vSwitch, you may use:
mininet/util/install.sh -fnv
This should be reasonably quick, and the following command should
work after the installation:
sudo mn --test pingall
To install ALL of the software which we use for OpenFlow tutorials,
including POX, the OpenFlow WireShark dissector, the `oftest`
framework, and other potentially useful software, you may use:
mininet/util/install.sh -a
This takes about 4 minutes on our test system.
You can change the directory where the dependencies are installed using
the -s <directory> flag.
mininet/util/install.sh -s <directory> -a
3.2. Native installation from source on Fedora 18+.
As root execute the following operations:
* install git
yum install git
* create an user account (e.g. mininet) and add it to the wheel group
useradd [...] mininet
usermod -a -G wheel mininet
* change the SElinux setting to permissive. It can be done
temporarily with:
setenforce 0
then login with the new account (e.g. mininet) and do the following:
* clone the Mininet repository
git clone git://github.com/mininet/mininet.git
* install Mininet, the OpenFlow reference implementation, and
Open vSwitch
mininet/util/install.sh -fnv
* enable and start openvswitch
sudo systemctl enable openvswitch
sudo systemctl start openvswitch
* test the mininet installation
sudo mn --test pingall
4. Creating your own Mininet/OpenFlow tutorial VM
Creating your own Ubuntu Mininet VM for use with the OpenFlow tutorial
is easy! First, create a new Ubuntu VM. Next, run two commands in it:
wget https://raw.github.com/mininet/mininet/master/util/vm/install-mininet-vm.sh
time install-mininet-vm.sh
Finally, verify that Mininet is installed and working in the VM:
sudo mn --test pingall
5. Installation on other Linux distributions
Although we don't support other Linux distributions directly, it
should be possible to install and run Mininet with some degree of
manual effort.
In general, you must have:
* A Linux kernel compiled with network namespace support enabled
* An OpenFlow implementation (either the reference user or kernel
space implementations, or Open vSwitch.) Appropriate kernel
modules (e.g. tun and ofdatapath for the reference kernel
implementation) must be loaded.
* Python, `bash`, `ping`, `iperf`, etc.
* Root privileges (required for network device access)
We encourage contribution of patches to the `install.sh` script to
support other Linux distributions.
Good luck!
Mininet Team
---
-33
View File
@@ -1,33 +0,0 @@
Mininet 2.1.0p1 License
Copyright (c) 2013 Open Networking Laboratory
Copyright (c) 2009-2012 Bob Lantz and The Board of Trustees of
The Leland Stanford Junior University
Original authors: Bob Lantz and Brandon Heller
We are making Mininet available for public use and benefit with the
expectation that others will use, modify and enhance the Software and
contribute those enhancements back to the community. However, since we
would like to make the Software available for broadest use, with as few
restrictions as possible permission is hereby granted, free of charge, to
any person obtaining a copy of this Software to deal in the Software
under the copyrights without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
The name and trademarks of copyright holder(s) may NOT be used in
advertising or publicity pertaining to the Software or any derivatives
without specific, written prior permission.
-67
View File
@@ -1,67 +0,0 @@
MININET = mininet/*.py
TEST = mininet/test/*.py
EXAMPLES = mininet/examples/*.py
MN = bin/mn
BIN = $(MN)
PYSRC = $(MININET) $(TEST) $(EXAMPLES) $(BIN)
MNEXEC = mnexec
MANPAGES = mn.1 mnexec.1
P8IGN = E251,E201,E302,E202
BINDIR = /usr/bin
MANDIR = /usr/share/man/man1
DOCDIRS = doc/html doc/latex
PDF = doc/latex/refman.pdf
CFLAGS += -Wall -Wextra
all: codecheck test
clean:
rm -rf build dist *.egg-info *.pyc $(MNEXEC) $(MANPAGES) $(DOCDIRS)
codecheck: $(PYSRC)
-echo "Running code check"
util/versioncheck.py
pyflakes $(PYSRC)
pylint --rcfile=.pylint $(PYSRC)
pep8 --repeat --ignore=$(P8IGN) $(PYSRC)
errcheck: $(PYSRC)
-echo "Running check for errors only"
pyflakes $(PYSRC)
pylint -E --rcfile=.pylint $(PYSRC)
test: $(MININET) $(TEST)
-echo "Running tests"
mininet/test/test_nets.py
mininet/test/test_hifi.py
mnexec: mnexec.c $(MN) mininet/net.py
cc $(CFLAGS) $(LDFLAGS) -DVERSION=\"`PYTHONPATH=. $(MN) --version`\" $< -o $@
install: $(MNEXEC) $(MANPAGES)
install $(MNEXEC) $(BINDIR)
install $(MANPAGES) $(MANDIR)
python setup.py install
develop: $(MNEXEC) $(MANPAGES)
# Perhaps we should link these as well
install $(MNEXEC) $(BINDIR)
install $(MANPAGES) $(MANDIR)
python setup.py develop
man: $(MANPAGES)
mn.1: $(MN)
PYTHONPATH=. help2man -N -n "create a Mininet network." \
--no-discard-stderr $< -o $@
mnexec.1: mnexec
help2man -N -n "execution utility for Mininet." \
-h "-h" -v "-v" --no-discard-stderr ./$< -o $@
.PHONY: doc
doc: man
doxygen doc/doxygen.cfg
make -C doc/latex
+22 -123
View File
@@ -1,133 +1,32 @@
Mininet: Rapid Prototyping for Software Defined Networks
========================================================
Mini-NDN
========
*The best way to emulate almost any network on your laptop!*
If you are new to the NDN community of software generally, read the
[Contributor's Guide](https://github.com/named-data/.github/blob/master/CONTRIBUTING.md).
Version 2.1.0p1
### What is Mini-NDN?
### What is Mininet?
Mini-NDN is a lightweight networking emulation tool that enables testing, experimentation, and
research on the NDN platform based on [Mininet](https://github.com/mininet/mininet).
Mini-NDN uses the NDN libraries, NFD, NLSR, and tools released by the
[NDN project](http://named-data.net/codebase/platform/) to emulate an NDN network on a single system.
Mininet emulates a complete network of hosts, links, and switches
on a single machine. To create a sample two-host, one-switch network,
just run:
Mini-NDN is open and free software licensed under the GPL 3.0 license. Mini-NDN is free to all
users and developers. For more information about licensing details and limitations,
please refer to [COPYING.md](COPYING.md).
`sudo mn`
Mininet is useful for interactive development, testing, and demos,
especially those using OpenFlow and SDN. OpenFlow-based network
controllers prototyped in Mininet can usually be transferred to
hardware with minimal changes for full line-rate execution.
### How does it work?
Mininet creates virtual networks using process-based virtualization
and network namespaces - features that are available in recent Linux
kernels. In Mininet, hosts are emulated as `bash` processes running in
a network namespace, so any code that would normally run on a Linux
server (like a web server or client program) should run just fine
within a Mininet "Host". The Mininet "Host" will have its own private
network interface and can only see its own processes. Switches in
Mininet are software-based switches like Open vSwitch or the OpenFlow
reference switch. Links are virtual ethernet pairs, which live in the
Linux kernel and connect our emulated switches to emulated hosts
(processes).
### Features
Mininet includes:
* A command-line launcher (`mn`) to instantiate networks.
* A handy Python API for creating networks of varying sizes and
topologies.
* Examples (in the `examples/` directory) to help you get started.
* Full API documentation via Python `help()` docstrings, as well as
the ability to generate PDF/HTML documentation with `make doc`.
* Parametrized topologies (`Topo` subclasses) using the Mininet
object. For example, a tree network may be created with the
command:
`mn --topo tree,depth=2,fanout=3`
* A command-line interface (`CLI` class) which provides useful
diagnostic commands (like `iperf` and `ping`), as well as the
ability to run a command to a node. For example,
`mininet> h11 ifconfig -a`
tells host h11 to run the command `ifconfig -a`
* A "cleanup" command to get rid of junk (interfaces, processes, files
in /tmp, etc.) which might be left around by Mininet or Linux. Try
this if things stop working!
`mn -c`
### New features in 2.1.0p1
Mininet 2.1.0p1 provides a number of bug fixes as well as
several new features, including:
* Convenient access to `Mininet()` as a dict of nodes
* X11 tunneling (wireshark in Mininet hosts, finally!)
* Accurate reflection of the `Mininet()` object in the CLI
* Automatically detecting and adjusting resource limits
* Automatic cleanup on failure of the `mn` command
* Preliminary support for running OVS in user space mode
* Preliminary support (`IVSSwitch()`) for the Indigo Virtual Switch
* support for installing the OpenFlow 1.3 versions of the reference
user switch and NOX from CPqD
* The ability to import modules from `mininet.examples`
We have provided several new examples (which can easily be
imported to provide useful functionality) including:
* Modeling separate control and data networks: `mininet.examples.controlnet`
* Connecting Mininet hosts the internet (or a LAN) using NAT: `mininet.examples.nat`
* Creating per-host custom directories using bind mounts: `mininet.examples.bind`
Note that examples contain experimental features which might
"graduate" into mainline Mininet in the future, but they should
not be considered a stable part of the Mininet API!
### Installation
See `INSTALL` for installation instructions and details.
The first release of Mini-NDN is developed by members of the NSF-sponsored NDN project team.
Mini-NDN is open to contribution from the public.
For more details, please refer to [AUTHORS.rst](AUTHORS.rst).
Bug reports and feedback are highly appreciated and can be made through our
[Redmine site](http://redmine.named-data.net/projects/mini-ndn) and the
[mini-ndn mailing list](http://www.lists.cs.ucla.edu/mailman/listinfo/mini-ndn).
### Documentation
In addition to the API documentation (`make doc`), much useful
information, including a Mininet walkthrough and an introduction
to the Python API, is available on the
[Mininet Web Site](http://mininet.org).
There is also a wiki which you are encouraged to read and to
contribute to, particularly the Frequently Asked Questions (FAQ.)
Please refer to http://minindn.memphis.edu/ or [docs/index.rst](docs/index.rst) for installation, usage, and other documentation.
The documentation can be built using:
### Support
./docs/build.sh
Mininet is community-supported. We encourage you to join the
Mininet mailing list, `mininet-discuss` at:
<https://mailman.stanford.edu/mailman/listinfo/mininet-discuss>
### Contributing
Mininet is an open source project and is currently hosted
at <https://github.com/mininet>. You are encouraged to download
the code, examine it, modify it, and submit bug reports, bug fixes,
feature requests, new features and other issues and pull requests.
Thanks to everyone who has contributed to the project
(see CONTRIBUTORS for more info!)
Best wishes, and we look forward to seeing what you can do with
Mininet to change the networking world!
### Credits
The Mininet 2.1.0p1 Team:
* Bob Lantz
* Brian O'Connor
and is available under `docs/_build/html`.
-299
View File
@@ -1,299 +0,0 @@
#!/usr/bin/env python
"""
Mininet runner
author: Brandon Heller (brandonh@stanford.edu)
To see options:
sudo mn -h
Example to pull custom params (topo, switch, etc.) from a file:
sudo mn --custom ~/mininet/custom/custom_example.py
"""
from optparse import OptionParser
import os
import sys
import time
# Fix setuptools' evil madness, and open up (more?) security holes
if 'PYTHONPATH' in os.environ:
sys.path = os.environ[ 'PYTHONPATH' ].split( ':' ) + sys.path
from mininet.clean import cleanup
from mininet.cli import CLI
from mininet.log import lg, LEVELS, info, debug, error
from mininet.net import Mininet, MininetWithControlNet, VERSION
from mininet.node import ( Host, CPULimitedHost, Controller, OVSController,
NOX, RemoteController, UserSwitch, OVSKernelSwitch,
OVSLegacyKernelSwitch, IVSSwitch )
from mininet.link import Link, TCLink
from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo
from mininet.topolib import TreeTopo
from mininet.util import custom, customConstructor
from mininet.util import buildTopo
# built in topologies, created only when run
TOPODEF = 'minimal'
TOPOS = { 'minimal': lambda: SingleSwitchTopo( k=2 ),
'linear': LinearTopo,
'reversed': SingleSwitchReversedTopo,
'single': SingleSwitchTopo,
'tree': TreeTopo }
SWITCHDEF = 'ovsk'
SWITCHES = { 'user': UserSwitch,
'ovsk': OVSKernelSwitch,
'ovsl': OVSLegacyKernelSwitch,
'ivs': IVSSwitch }
HOSTDEF = 'proc'
HOSTS = { 'proc': Host,
'rt': custom( CPULimitedHost, sched='rt' ),
'cfs': custom( CPULimitedHost, sched='cfs' ) }
CONTROLLERDEF = 'ovsc'
CONTROLLERS = { 'ref': Controller,
'ovsc': OVSController,
'nox': NOX,
'remote': RemoteController,
'none': lambda name: None }
LINKDEF = 'default'
LINKS = { 'default': Link,
'tc': TCLink }
# optional tests to run
TESTS = [ 'cli', 'build', 'pingall', 'pingpair', 'iperf', 'all', 'iperfudp',
'none' ]
ALTSPELLING = { 'pingall': 'pingAll',
'pingpair': 'pingPair',
'iperfudp': 'iperfUdp',
'iperfUDP': 'iperfUdp' }
def addDictOption( opts, choicesDict, default, name, helpStr=None ):
"""Convenience function to add choices dicts to OptionParser.
opts: OptionParser instance
choicesDict: dictionary of valid choices, must include default
default: default choice key
name: long option name
help: string"""
if default not in choicesDict:
raise Exception( 'Invalid default %s for choices dict: %s' %
( default, name ) )
if not helpStr:
helpStr = ( '|'.join( sorted( choicesDict.keys() ) ) +
'[,param=value...]' )
opts.add_option( '--' + name,
type='string',
default = default,
help = helpStr )
def version( *_args ):
"Print Mininet version and exit"
print "%s" % VERSION
exit()
class MininetRunner( object ):
"Build, setup, and run Mininet."
def __init__( self ):
"Init."
self.options = None
self.args = None # May be used someday for more CLI scripts
self.validate = None
self.parseArgs()
self.setup()
self.begin()
def setCustom( self, name, value ):
"Set custom parameters for MininetRunner."
if name in ( 'topos', 'switches', 'hosts', 'controllers' ):
# Update dictionaries
param = name.upper()
globals()[ param ].update( value )
elif name == 'validate':
# Add custom validate function
self.validate = value
else:
# Add or modify global variable or class
globals()[ name ] = value
def parseCustomFile( self, fileName ):
"Parse custom file and add params before parsing cmd-line options."
customs = {}
if os.path.isfile( fileName ):
execfile( fileName, customs, customs )
for name, val in customs.iteritems():
self.setCustom( name, val )
else:
raise Exception( 'could not find custom file: %s' % fileName )
def parseArgs( self ):
"""Parse command-line args and return options object.
returns: opts parse options dict"""
if '--custom' in sys.argv:
index = sys.argv.index( '--custom' )
if len( sys.argv ) > index + 1:
filename = sys.argv[ index + 1 ]
self.parseCustomFile( filename )
else:
raise Exception( 'Custom file name not found' )
desc = ( "The %prog utility creates Mininet network from the\n"
"command line. It can create parametrized topologies,\n"
"invoke the Mininet CLI, and run tests." )
usage = ( '%prog [options]\n'
'(type %prog -h for details)' )
opts = OptionParser( description=desc, usage=usage )
addDictOption( opts, SWITCHES, SWITCHDEF, 'switch' )
addDictOption( opts, HOSTS, HOSTDEF, 'host' )
addDictOption( opts, CONTROLLERS, CONTROLLERDEF, 'controller' )
addDictOption( opts, LINKS, LINKDEF, 'link' )
addDictOption( opts, TOPOS, TOPODEF, 'topo' )
opts.add_option( '--clean', '-c', action='store_true',
default=False, help='clean and exit' )
opts.add_option( '--custom', type='string', default=None,
help='read custom topo and node params from .py' +
'file' )
opts.add_option( '--test', type='choice', choices=TESTS,
default=TESTS[ 0 ],
help='|'.join( TESTS ) )
opts.add_option( '--xterms', '-x', action='store_true',
default=False, help='spawn xterms for each node' )
opts.add_option( '--ipbase', '-i', type='string', default='10.0.0.0/8',
help='base IP address for hosts' )
opts.add_option( '--mac', action='store_true',
default=False, help='automatically set host MACs' )
opts.add_option( '--arp', action='store_true',
default=False, help='set all-pairs ARP entries' )
opts.add_option( '--verbosity', '-v', type='choice',
choices=LEVELS.keys(), default = 'info',
help = '|'.join( LEVELS.keys() ) )
opts.add_option( '--innamespace', action='store_true',
default=False, help='sw and ctrl in namespace?' )
opts.add_option( '--listenport', type='int', default=6634,
help='base port for passive switch listening' )
opts.add_option( '--nolistenport', action='store_true',
default=False, help="don't use passive listening " +
"port")
opts.add_option( '--pre', type='string', default=None,
help='CLI script to run before tests' )
opts.add_option( '--post', type='string', default=None,
help='CLI script to run after tests' )
opts.add_option( '--pin', action='store_true',
default=False, help="pin hosts to CPU cores "
"(requires --host cfs or --host rt)" )
opts.add_option( '--version', action='callback', callback=version )
self.options, self.args = opts.parse_args()
# We don't accept extra arguments after the options
if self.args:
opts.print_help()
exit()
def setup( self ):
"Setup and validate environment."
# set logging verbosity
if LEVELS[self.options.verbosity] > LEVELS['output']:
print ( '*** WARNING: selected verbosity level (%s) will hide CLI '
'output!\n'
'Please restart Mininet with -v [debug, info, output].'
% self.options.verbosity )
lg.setLogLevel( self.options.verbosity )
def begin( self ):
"Create and run mininet."
if self.options.clean:
cleanup()
exit()
start = time.time()
topo = buildTopo( TOPOS, self.options.topo )
switch = customConstructor( SWITCHES, self.options.switch )
host = customConstructor( HOSTS, self.options.host )
controller = customConstructor( CONTROLLERS, self.options.controller )
link = customConstructor( LINKS, self.options.link )
if self.validate:
self.validate( self.options )
inNamespace = self.options.innamespace
Net = MininetWithControlNet if inNamespace else Mininet
ipBase = self.options.ipbase
xterms = self.options.xterms
mac = self.options.mac
arp = self.options.arp
pin = self.options.pin
listenPort = None
if not self.options.nolistenport:
listenPort = self.options.listenport
mn = Net( topo=topo,
switch=switch, host=host, controller=controller,
link=link,
ipBase=ipBase,
inNamespace=inNamespace,
xterms=xterms, autoSetMacs=mac,
autoStaticArp=arp, autoPinCpus=pin,
listenPort=listenPort )
if self.options.pre:
CLI( mn, script=self.options.pre )
test = self.options.test
test = ALTSPELLING.get( test, test )
mn.start()
if test == 'none':
pass
elif test == 'all':
mn.start()
mn.ping()
mn.iperf()
elif test == 'cli':
CLI( mn )
elif test != 'build':
getattr( mn, test )()
if self.options.post:
CLI( mn, script=self.options.post )
mn.stop()
elapsed = float( time.time() - start )
info( 'completed in %0.3f seconds\n' % elapsed )
if __name__ == "__main__":
try:
MininetRunner()
except KeyboardInterrupt:
info( "\n\nKeyboard Interrupt. Shutting down and cleaning up...\n\n")
cleanup()
except Exception:
# Print exception
type_, val_, trace_ = sys.exc_info()
errorMsg = ( "-"*80 + "\n" +
"Caught exception. Cleaning up...\n\n" +
"%s: %s\n" % ( type_.__name__, val_ ) +
"-"*80 + "\n" )
error( errorMsg )
# Print stack trace to debug log
import traceback
stackTrace = traceback.format_exc()
debug( stackTrace + "\n" )
cleanup()
-6
View File
@@ -1,6 +0,0 @@
This directory should hold configuration files for custom mininets.
See custom_example.py, which loads the default minimal topology. The advantage of defining a mininet in a separate file is that you then use the --custom option in mn to run the CLI or specific tests with it.
To start up a mininet with the provided custom topology, do:
sudo mn --custom custom_example.py --topo mytopo
-34
View File
@@ -1,34 +0,0 @@
"""Custom topology example
Two directly connected switches plus a host for each switch:
host --- switch --- switch --- host
Adding the 'topos' dict with a key/value pair to generate our newly defined
topology enables one to pass in '--topo=mytopo' from the command line.
"""
from mininet.topo import Topo
class MyTopo( Topo ):
"Simple topology example."
def __init__( self ):
"Create custom topo."
# Initialize topology
Topo.__init__( self )
# Add hosts and switches
leftHost = self.addHost( 'h1' )
rightHost = self.addHost( 'h2' )
leftSwitch = self.addSwitch( 's3' )
rightSwitch = self.addSwitch( 's4' )
# Add links
self.addLink( leftHost, leftSwitch )
self.addLink( leftSwitch, rightSwitch )
self.addLink( rightSwitch, rightHost )
topos = { 'mytopo': ( lambda: MyTopo() ) }
-33
View File
@@ -1,33 +0,0 @@
mininet (2.1.0-0ubuntu1) saucy; urgency=low
* Add 2.1.0 final packaging
-- Bob Lantz <rlantz@cs.stanford.edu> Wed, 18 Sep 2013 22:43:47 -0700
mininet (2.1.0~rc1-0ubuntu1) saucy; urgency=low
* New upstream release candidate:
- d/control: Drop dependency on python-networkx, add iperf, socat
and cgroup-bin to Depends.
-- James Page <james.page@ubuntu.com> Wed, 28 Aug 2013 10:10:20 +0100
mininet (2.0.0-0ubuntu1) raring; urgency=low
* New upstream release.
-- James Page <james.page@ubuntu.com> Wed, 19 Dec 2012 15:48:01 +0000
mininet (2.0.0~rc1-0ubuntu1) quantal; urgency=low
* New upstream release.
* Update copyright to match upstream release
* Fix this message
-- Bob Lantz <rlantz@cs.stanford.edu> Sun, 18 Nov 2012 00:15:09 -0800
mininet (2.0.0~d4-0ubuntu1) quantal; urgency=low
* Initial release.
-- Bob Lantz <rlantz@cs.stanford.edu> Tue, 07 Aug 2012 14:11:27 -0700
-1
View File
@@ -1 +0,0 @@
9
-31
View File
@@ -1,31 +0,0 @@
Source: mininet
Section: net
Priority: extra
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
XSBC-Original-Maintainer: Bob Lantz <rlantz@cs.stanford.edu>
Standards-Version: 3.9.3
Build-Depends:
debhelper (>= 9~),
help2man,
python-dev,
python-pkg-resources,
python-setuptools
Homepage: http://openflow.org/mininet
Package: mininet
Architecture: any
Depends:
openvswitch-switch,
telnet,
socat,
iperf,
cgroup-bin,
${misc:Depends},
${python:Depends},
${shlibs:Depends}
Recommends: openvswitch-controller
Description: Process-based network emulator
Mininet is a network emulator which uses lightweight
virtualization to create virtual networks for rapid
prototyping of Software-Defined Network (SDN) designs
using OpenFlow.
-37
View File
@@ -1,37 +0,0 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0
Upstream-Name: mininet
Source: https://github.com/mininet/mininet
Files: *
Copyright: 2012-2013 Open Networking Laboratory,
2009-2012 Bob Lantz,
2009-2012 The Board of Trustees of the Leland Stanford Junior
University
License:
Original authors: Bob Lantz and Brandon Heller
.
We are making Mininet available for public use and benefit with the
expectation that others will use, modify and enhance the Software and
contribute those enhancements back to the community. However, since we
would like to make the Software available for broadest use, with as few
restrictions as possible permission is hereby granted, free of charge, to
any person obtaining a copy of this Software to deal in the Software
under the copyrights without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
.
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
.
The name and trademarks of copyright holder(s) may NOT be used in
advertising or publicity pertaining to the Software or any derivatives
without specific, written prior permission.
Vendored
-1
View File
@@ -1 +0,0 @@
README.md
-1
View File
@@ -1 +0,0 @@
examples/*
-1
View File
@@ -1 +0,0 @@
mnexec /usr/bin
-1
View File
@@ -1 +0,0 @@
*.1
-12
View File
@@ -1,12 +0,0 @@
#!/usr/bin/make -f
%:
dh $@ --buildsystem=python_distutils --with=python2
override_dh_auto_build:
make man
make mnexec
dh_auto_build
get-orig-source:
uscan --force-download --rename
-1
View File
@@ -1 +0,0 @@
3.0 (quilt)
-3
View File
@@ -1,3 +0,0 @@
version=3
opts=filenamemangle=s/(.*)\/archive/$1/,uversionmangle=s/([abdr].*)\.tar\.gz/~$1/ \
https://github.com/mininet/mininet/tags .*/archive\/(\d.*\.tar\.gz)
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
# set python3 alias, but needs permanent fix in image directly
alias python=python3
service openvswitch-switch start
ovs-vsctl set-manager ptcp:6640
bash
service openvswitch-switch stop
+35
View File
@@ -0,0 +1,35 @@
[comments]: The original author of Mini-NDN docker is Md Ashiqur Rahman (marahman@email.arizona.edu)
## Running Mini-NDN inside Docker
You can use the nightly build from GitHub package registry
```bash
docker run -m 4g --cpus=4 -it --privileged \
-v /lib/modules:/lib/modules \
ghcr.io/named-data/mini-ndn:master bash
```
## Building your own image
The Dockerfile can be used directly to `build` an image from scratch.
* Build with `Dockerfile`:
* Clone the repository and type.
```bash
docker build -t minindn .
```
* You can then access the container through shell with,
```bash
docker run -m 4g --cpus=4 -it --privileged \
-v /lib/modules:/lib/modules \
minindn bin/bash
```
### Notes:
* Memory (-m), CPU (--cpus) are recommended by Mini-NDN.
* `--privileged` is mandatory for underlying [Mininet](http://mininet.org/) to utilize virtual switch
* Root directory on `run` is `/mini-ndn` containing the installation and examples.
* GUI may not work for now due to docker and xterm setup issues and is independent from Mini-NDN.
If you intend to run the GUI, pass `-e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix` to the `docker run` command.
+20
View File
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+1
View File
@@ -0,0 +1 @@
.. include:: ../AUTHORS.rst
Executable
+36
View File
@@ -0,0 +1,36 @@
#!/bin/bash
# -*- Mode:bash; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2021, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
set -eo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")"
PIP='python3 -m pip'
for PIPPKG in sphinx sphinx_rtd_theme; do
if ! $PIP show $PIPPKG >/dev/null; then
sudo $PIP install $PIPPKG
fi
done
make clean html
+61
View File
@@ -0,0 +1,61 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
from datetime import datetime
from minindn import __version__
# -- Project information -----------------------------------------------------
project = 'Mini-NDN'
copyright = '2015-{}, Mini-NDN. This research is partially supported by NSF.'.format(datetime.now().year)
author = 'Mini-NDN'
# The full version, including alpha/beta/rc tags
release = __version__
version = __version__
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Need to specify the line below if custom conf.py
# https://github.com/readthedocs/readthedocs.org/issues/2569
# https://stackoverflow.com/questions/56336234/build-fail-sphinx-error-contents-rst-not-found
master_doc = 'index'
+274
View File
@@ -0,0 +1,274 @@
Experiment
==========
Configuration
-------------
Mini-NDN uses a configuration file describing the topology and its parameters to setup a network.
The [nodes] section:
At the bare minimum, the node section describes the nodes present in the
topology.
::
[nodes]
a: key1=value1 key2=value2
b: key1=value1
Any key and value passed here is accessible in Mini-NDN as:
::
ndn = Minindn(...)
value = ndn.net.hosts[0].params['params'].get('key1', "defaultValue")
One can specify log levels for each node's NFD and NLSR using this key-value system:
::
[nodes]
a: nfd-log-level=DEBUG nlsr-log-level=DEBUG
b: nfd-log-level=INFO
To specify a log level for certain modules of NFD, the following line can be added to `nfd.py`:
::
node.cmd('infoedit -f {} -s log.Forwarder -v {}'.format(self.confFile, 'INFO'))
This will turn on FORWARDER logging to INFO for all nodes.
.. Todo: Add switch section
The [links] section:
The links section describes the links in the topology.
::
e.g.)
[links]
a:b delay=10ms
This would create a link between a and b. 'b:a' would also result in the
same. The following parameters can be configured for a node:
- delay : Delay parameter is a required parameter which defines the
delay of the link (1-1000ms)
- bw : Bandwidth of a link (<1-1000> Mbps)
- loss : Percentage of packet loss (<1-100>)
Example configuration file
::
[nodes]
a:
b:
[links]
a:b delay=10ms bw=100
See ``ndn_utils/topologies`` for more sample files
Sample
------
Sample experiment may written as follows:
.. code:: python
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.appmanager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from minindn.helpers.routing_helper import IPRoutingHelper
if __name__ == '__main__':
setLogLevel('info')
Minindn.cleanUp()
Minindn.verifyDependencies()
# Can pass a custom parser, custom topology, or any Mininet params here
ndn = Minindn()
ndn.start()
# IP reachability if needed
# IPRoutingHelper.calcAllRoutes(ndn.net)
# info("IP routes configured, start ping\n")
# ndn.net.pingAll()
# Start apps with AppManager which registers a clean up function with ndn
info('Starting NFD on nodes\n')
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
info('Starting NLSR on nodes\n')
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr)
# or can not start NLSRs with some delay in between:
# nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr)
# for host in ndn.net.hosts:
# nlsrs.startOnNode(host)
# time.sleep(30)
MiniNDNCLI(ndn.net)
# Calls the clean up functions registered via AppManager
ndn.stop()
Users may look at how the NFD and NLSR applications are written as a sub class of Application
in the ``minindn/apps`` folder. Or users may choose to directly run their application on nodes
such as ndnpingserver is run in ``minindn/helpers/experiment.py``.
**Note:** A certain log-level can be set-up for all the NFD or NLSR nodes at once by passing it as an argument during the startup.
``nfds = AppManager(self.ndn, self.ndn.net.hosts, Nfd, logLevel='DEBUG')`` (same for NLSR)
Execution
---------
To run Mini-NDN with the default topology,
``ndn_utils/topologies/default-topology.conf``, type:
::
sudo python examples/minindn.py
To run Mini-NDN with a topology file, provide the filename as the first
argument:
::
sudo python examples/minindn.py my-topology.conf
After Mini-NDN is installed, users can run examples from anywhere with python directly as follows:
::
sudo python /path/to/myexample.py
The user no longer needs to create an experiment in the old Mini-NDN way, then install it to the system before executing it via the minindn binary. The new examples can be separate from the Mini-NDN folder if the core is not being modified.
CLI Interface
_____________
During set up, the list of nodes in the network will be listed as they
are initialized:
::
*** Adding hosts:
a b c d
After set up, the command-line interface (CLI) will display a prompt.
::
mini-ndn>
To interact with a node, first type the node's name and then the command
to be executed:
::
mini-ndn> a echo "Hello, world!"
Hello, world!
To see the status of the forwarder on the node:
::
mini-ndn> a nfdc status report
To see the status of routing on the node:
::
mini-ndn> a nlsrc status
To exit Mini-NDN, type ``quit`` in the CLI or use ``ctrl + D``:
::
mini-ndn> quit
``Ctrl + C`` is used to quit an application run in the foreground of the command line.
For a more in depth explanation of the CLI, please see the `Mininet
Walkthrough <http://mininet.org/walkthrough/>`__.
To run NDN commands from the outside the command line user can also open a new terminal
and export the HOME folder of a node ``export HOME=/tmp/minindn/a && cd ~``
Working Directory Structure
---------------------------
Currently Mini-NDN uses /tmp/minindn as the working directory if not
specified otherwise by using the option --work-dir.
Each node is given a HOME directory under /tmp/minindn/<node-name> where
<node-name> is the name of the node specified in the [nodes] section of
the conf file.
NFD
___
- NFD conf file is stored at ``/tmp/minindn/<node-name>/nfd.conf``
- NFD log file is stored at ``/tmp/minindn/<node-name>/log/nfd.log``
- ``.ndn`` folder is stored at ``/tmp/minindn/<node-name>/.ndn``
NLSR
____
- NLSR conf file is stored at ``/tmp/minindn/<node-name>/nlsr.conf``
- NLSR log file is stored at ``/tmp/minindn/<node-name>/log/nlsr.log``
When security is enabled, NLSR security certificates are stored in:
``/tmp/minindn/<node-name>/security`` Note that no NLSR publishes the root
certificate, Mini-NDN installs root.cert in security folder for each
NLSR.
While a host's NLSR neighbors are by default populated by adjacent nodes in wired scenarios,
for those running NLSR on wifi stations it is required that you specify "neighbor" faces
manually. The framework for this is provided either via a dictionary object or through
additional sections in topology files, and may also be used for wired experiments.
See an example of a topo of this sort in ``mini-ndn/topologies/wifi/nlsr_wifi_example.conf``.
NLSR faces to be created can be manually specified from topology files in a ``[faces]``
section, with the format ``nodeA:nodeB [cost=X]``. You should then call the ``setupFaces()``
method of an initialized Mini-NDN object to get a dictionary based on this parse in the format
``faceA:[(faceB, cost), (faceC, cost),...]``, which can finally be passed to the NLSR
helper via the faceDict parameter. An example experiment using this methodology is located
at ``mini-ndn/examples/wifi/nlsr_wifi.py``. Note that the aforementioned dict can also be
created manually in the previously established format.
Routing Options
----------------
Link State Routing (NLSR)
_________________________
By default, Mini-NDN uses `NLSR <https://github.com/named-data/NLSR>`__ for route management i.e route computation, route installation and so on. Additionally, the command line utility ``nlsrc`` can be used to advertise and withdraw prefixes and route status.
NDN Routing Helper
____________________
Computes link-state or hyperbolic route/s from a given minindn topology and installs them in the FIB. The major benefit of the routing helper is to eliminate the overhead of NLSR when using larger topology. See ``examples/static_routing_experiment.py`` on how to use the helper class.
**IMPORTANT:** NLSR and NDN Routing Helper are mutually exclusive, meaning you can only use one at a time, not both.
**Note:** The current version of ``ndn_routing_helper`` is still in the experimental phase. It doesn't support node or link failure and runtime prefix advertisement/withdrawal. If you find any bug please report `here <https://redmine.named-data.net/projects/mini-ndn>`__ or contact the :doc:`authors <authors>`.
IP Routing Helper
____________________
The routing helper allows to run IP-based evaluations with Mini-NDN. It configures static IP routes to all nodes, which means that all nodes can reach all other nodes in the network
reachable, even when relaying is required. Please see ``examples/ip_rounting_experiment.py`` for a simple example.
+48
View File
@@ -0,0 +1,48 @@
FAQ
=========
* ``How does Mini-NDN work?``
Mini-NDN's principles of operation most heavily rely on the underlying Mininet code it relies on.
Mininet uses a combination of limited containerization via network namespaces (which give processes
isolated interfaces and routing tables) and emulated ethernet connections via veth connections.
In practical terms, Mini-NDN ensures that processes running on distinct nodes will run seperately
and without interfering with each other.
* ``How does Mini-NDN apply link loss/delay/etc.?``
Mini-NDN relies on Mininet's code, which in turn uses the Linux tc utility on a stations' virtualized
interfaces to apply configurations known as qdiscs to these links. Note that these will only be applied
on egress packets from a station where it's applied.
For more information on qdiscs and tc, view the information `here <http://wiki.linuxwall.info/doku.php/en%3aressources%3adossiers%3anetworking%3atraffic_control>`_.
* ``Why use Mini-NDN rather than a simulator such as ndnSIM?``
Mini-NDN is easier and faster to use because, rather than serving as a mathematical model of a network,
it is instead running real NDN code on a real Linux kernel. This also means it's quite useful for testing code changes, as it can more accurately test the interaction of software componenents.
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Criteria | Mini-NDN | ndnSIM |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Based On | Mininet | ns-3 |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Language | Python | C++ |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Library/Forwarder/Applications | Use system binaries (free to use any compatible versions) | Integrated (fixed release version) |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Application language | C++ (ndn-cxx), CCL (ndn-cpp, PyNDN, ndn-js, jNDN) | C++ (ndn-cxx) |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Simulation size | Medium - Large (cluster edition in development) | Large (can be parallelized using MPI) |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Simulation time | Real time | Quick (depending on size/memory) |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Porting real applications | Drop in | Changes required |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Interactivity | Can interact directly with NFD, NLSR or Apps | Can show stats while running |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Logs | May need to manually setup to collect | Available with tracer |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Post processing scripts | Not available, users need to write their own | Available to use to process the logs |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
| Other | Not yet supported (Wifi in development) | WiFi, LTE, etc available from ns-3 |
+--------------------------------+-----------------------------------------------------------+-----------------------------------------+
+10
View File
@@ -0,0 +1,10 @@
Past NDN Hackathon projects
===========================
- 1st NDN Hackathon: `NFD integration test <http://ndncomm.github.io/mini-ndn/>`_.
- 2st NDN Hackathon: `Mini-NDN metrics <https://github.com/2nd-ndn-hackathon/mini-ndn-metrics>`_.
- 3rd NDN Hackathon: `Mini-NDN cluster <https://github.com/3rd-ndn-hackathon/mini-NDN-cluster>`_.
- 4th NDN Hackathon: `Mini-NDN wifi <https://github.com/4th-ndn-hackathon/Mini-NDN-Wi-Fi>`_.
- 7th NDN Hackathon: `Mini-NDN documentation <https://github.com/7th-ndn-hackathon/mini-ndn-documentation>`_.
- 11th NDN Hackathon: `Mini-NDN improvements <https://11th-ndn-hackathon.named-data.net/hacks.html#8-mini-ndn-improvements>`_.
- 12th NDN Hackathon: `Mini-NDN improvements and Refactoring <https://12th-ndn-hackathon.named-data.net/hacks.html#7-mini-ndn-improvements>`_.
+128
View File
@@ -0,0 +1,128 @@
Howtos
======
Connect Mini-NDN nodes to an outside network
---------------------------------------------
Mini-NDN nodes can be connected to an outside network indirectly by
running NFD on the local machine:
::
(Mini-NDN node) ------ (NFD running on the host machine where Mini-NDN is running) ------- (External Network)
Add a node in root namespace
____________________________
For this simple example, we can use a single node topology with node 'a'
If we want node 'a' to connect to the host machine, we need to add a
"root" node which has a link with node "a."
Then the following code can be used:
.. code:: python
topo = Topo()
root = topo.addHost('root', inNamespace=False)
a = topo.addHost('a')
topo.addLink(root, a, delay='10ms')
ndn = Minindn(topo=topo)
...
Configuration
_____________
Run Mini-NDN with the above code and issue ifconfig on the local
machine to confirm the addition of the interface. You should be able to
locate "root-eth0":
::
root-eth0 Link encap:Ethernet HWaddr 3e:eb:77:d2:6f:1f
inet addr:1.0.0.9 Bcast:1.0.0.11 Mask:255.255.255.252
inet6 addr: fe80::3ceb:77ff:fed2:6f1f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:34 errors:0 dropped:0 overruns:0 frame:0
TX packets:33 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2667 (2.6 KB) TX bytes:2797 (2.7 KB)
To make the IP address associated with this interface persistent, add
the following line to /etc/network/interfaces and reboot your machine:
::
iface root-eth0 inet manual
Check connection
________________
After rebooting, run Mini-NDN and issue the following command:
::
mini-ndn>net
a a-eth0:b-eth0 a-eth1:c-eth0 a-eth2:root-eth0
Node "a" is connected to "root-eth0". Now issue "ifconfig a-eth2" on
node "a":
::
mini-ndn>a ifconfig a-eth2
a-eth2 Link encap:Ethernet HWaddr fa:76:d4:86:d3:ba
inet addr:1.0.0.10 Bcast:1.0.0.11 Mask:255.255.255.252
As learned from the previous step, the IP address of root-eth0 is
1.0.0.9.
::
mini-ndn>a ping 1.0.0.9
PING 1.0.0.9 (1.0.0.9) 56(84) bytes of data.
64 bytes from 1.0.0.9: icmp_seq=1 ttl=64 time=0.137 ms
64 bytes from 1.0.0.9: icmp_seq=2 ttl=64 time=0.123 ms
The host machine will also be able to ping node "a":
::
VirtualBox:~$ ping 1.0.0.10
PING 1.0.0.10 (1.0.0.10) 56(84) bytes of data.
64 bytes from 1.0.0.10: icmp_seq=1 ttl=64 time=0.086 ms
Run NFD on local machine and register route
___________________________________________
Start NFD on the local machine by using:
::
sudo nfd
The "nfd-start" script cannot be used, since the script allows only one
instance of NFD at a time. The NFD processes running on the Mini-NDN
nodes will prevent the "nfd-start" script from working.
Now, using "nfdc register", we can register a route from node "a" in
Mini-NDN to the NFD process on the host machine and from the host
machine to an external machine.
Also, if the local machine has a public IP, Mini-NDN nodes can be
reached via external machines.
Generate NDN testbed topology
___________________________________________
Run the following install.sh command
::
python3 util/testbed_topo_generator.py
This will place a "testbed.conf" file in the topologies subdirectory,
where it can be referenced as desired. To update the topology, simply
rerun this command.
+30
View File
@@ -0,0 +1,30 @@
.. Mini-NDN documentation master file, created by
sphinx-quickstart on Mon Sep 23 11:15:54 2019.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Mini-NDN: A Mininet-based NDN emulator
======================================
.. toctree::
:maxdepth: 2
:caption: Contents
introduction
install
experiment
howtos
release-notes
faq
hackathon
videos
Helpful Links
-------------
* `NDN Website <http://named-data.net/>`_
* `NDN Contributor's Guide <https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md>`_
* `Mininet Documentation <http://mininet.org/>`_
* `Mini-NDN redmine <https://redmine.named-data.net/projects/mini-ndn>`_
* `Mailing list <http://www.lists.cs.ucla.edu/mailman/listinfo/mini-ndn>`_
* :doc:`Mini-NDN Team <authors>`
+184
View File
@@ -0,0 +1,184 @@
Install
=======
Prerequisites
-------------
Mini-NDN is tested on the following Linux distributions:
- Ubuntu 20.04 (recommended)
- Ubuntu 22.04
- Debian 11 (WiFi scenario does not work)
- Fedora 33 (WiFi scenario does not work)
You must have sudo privileges to install and run Mini-NDN.
Using Vagrantfile
-----------------
With Vagrant installed, simply do ``vagrant up`` which will bring up an Ubuntu 18.04 virtual machine
and install Mini-NDN and all its dependencies on it. Please make sure to tweak the CPU core count
(default 4 cores) and RAM (default 4GB) according to your needs before doing vagrant up. Mini-NDN
can be found in /home/vagrant/mini-ndn which is a symlink to /vagrant if Vagrantfile was used from within mini-ndn cloned on the host. Otherwise it is an actual clone of mini-ndn.
Using install.sh
----------------
Mini-NDN has the following dependencies:
- `NDN Forwarding Daemon (NFD) <https://named-data.net/doc/NFD/>`_
- `Named Data Link State Routing (NLSR) <https://named-data.net/doc/NLSR/>`_
- `NDN Essential Tools (ndn-tools) <https://github.com/named-data/ndn-tools>`_
- `NDN Traffic Generator <https://github.com/named-data/ndn-traffic-generator>`_
- `infoedit <https://github.com/NDN-Routing/infoedit>`_
- `Mininet <http://mininet.org/>`_
- `Mininet-WiFi <https://mininet-wifi.github.io/>`_ (optional)
To install Mini-NDN and its dependencies, clone this repository and run:
::
./install.sh
The script accepts various command line flags.
Some notable flags are:
- ``-y`` skips interactive confirmation before installation.
- ``--ppa`` prefers installing NDN software from `named-data PPA <https://launchpad.net/~named-data/+archive/ubuntu/ppa>`_.
This shortens installation time by downloading binary packages, but is only available on Ubuntu.
- ``--source`` prefers installing NDN software from source code.
IMPORTANT: For now, Mininet-WiFi only works with ``--source`` installation because the current NFD release (0.7.1) doesn't
incorporate `issue 5155 <https://redmine.named-data.net/issues/5155>`, a required patch for WiFi module to work properly.
With the next NFD release, Mininet-WiFi will work with both ``source`` and ``ppa``. Alternatively, you can
checkout (at your own risk) a third-party source "`Use NFD nightly with Mini-NDN <https://yoursunny.com/t/2021/NFD-nightly-minindn/>`", which provides
NFD-nightly version and contains all the necessary patches.
- ``--dummy-keychain`` patches ndn-cxx to use an in-memory dummy KeyChain, which reduces CPU overhead
and allows you to scale up Mini-NDN experiments. Large Mini-NDN experiments would run significantly
faster after applying this patch. However, your experiments cannot use any NDN security related
features (signatures, verifier, access control, etc).
- ``--no-wifi`` skips Mininet-WiFi dependency.
Currently Mininet-WiFi only works on Ubuntu, so that you must specify this option when installing on other distros.
You can see all command line flags by running:
::
./install.sh -h
The script uses ``setup.py develop`` to point the system install of Python packages to the codebase
directory. Therefore, you can modify ``mininet``, ``mininet-wifi``, and ``mini-ndn``, and the
changes will be reflected immediately.
If NDN software is installed from source code (not PPA), the code is downloaded to ``dl`` directory
under your ``mini-ndn`` clone. If you modify the source code, you need to manually recompile and
reinstall the software (``./waf && sudo ./waf install``).
Installing Dependencies
-----------------------
This section outlines how to install dependnecies manually.
If you used ``install.sh``, you do not need to perform these steps.
Mininet
_______
Mini-NDN is based on Mininet. To install Mininet:
::
git clone --depth 1 https://github.com/mininet/mininet.git
After Mininet source is on your system, run the following command to
install Mininet core dependencies and Open vSwitch:
::
./util/install.sh -nv
To check if Mininet is working correctly, run this test:
::
sudo mn --test pingall
This will print out a series of statements that show the test setup and
the results of the test. Look for ``Results:`` two-thirds of the way
down where it will indicate the percentage of dropped packets. Your
results should show "0% dropped (2/2 received)".
NOTE: Mini-NDN, while providing a high level of emulation of hosts,
requires programs to be installed onto your computer. It will not work
if they are not installed. If you do not want NDN software installed
onto your computer, you can use a virtual machine, which can be quite
simply set up with the provided Vagrantfile.
NDN dependencies
________________
Each node in Mini-NDN will run the official implementation of NDN
installed on your system. The following dependencies are needed:
Mini-NDN uses NFD, NLSR, and ndn-tools.
- To install NFD: https://named-data.net/doc/NFD/current/INSTALL.html
- To install NLSR: https://named-data.net/doc/NLSR/current/INSTALL.html
- To install ndn-tools: https://github.com/named-data/ndn-tools
.. warning::
Please do not try to install NDN software from both the source (GitHub) and PPA (apt).
It will not work in most cases! If you used ./install.sh -a in the past but now want
to use apt, please run ``sudo ./waf uninstall`` in all the NDN projects before proceeding
with apt. Similarly, remove from apt if switching to source.
Please see the :ref:`scaling-note <scaling-note>` to learn about disabling
security for better scalability.
Note that all three of these can be installed from the Named Data PPA.
Instructions for setting it up can be found in the NFD installation
instructions. Note that PPA and installs from source **cannot** be
mixed. You must completely remove PPA installs from the system if switching
to source and vice-versa.
For PPA installs, if you are using a custom nfd.conf file in an experiment, you should
place it in /usr/local/etc/ndn/ rather than /etc/ndn/. This is to avoid
a bug from the default configuration file for the PPA, which is
incompatible with Mini-NDN.
Infoedit
________
Infoedit is used to edit configuration files for NFD and NLSR.
To install infoedit:
::
git clone --depth 1 https://github.com/NDN-Routing/infoedit
cd infoedit
make
sudo make install
Verification
------------
You can execute the following example to bring up the Mini-NDN command line
with NFD and NLSR running on each node:
::
sudo python examples/mnndn.py
You can use these steps to run the sample pingall experiment:
1. Issue the command: ``sudo python examples/nlsr/pingall.py``
2. When the ``mini-ndn>`` CLI prompt appears, the experiment has
finished. On the Mini-NDN CLI, issue the command ``exit`` to exit the
experiment.
3. Issue the command:
``grep -c content /tmp/minindn/*/ping-data/*.txt``. Each file should
report a count of 50.
4. Issue the command:
``grep -c timeout /tmp/minindn/*/ping-data/*.txt``. Each file should
report a count of 0.
+40
View File
@@ -0,0 +1,40 @@
Introduction
=================
If you are new to the NDN community of software generally, read the
`Contributor's Guide <https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md>`_.
What is Mini-NDN?
-----------------
Mini-NDN is a lightweight networking emulation tool that enables testing, experimentation, and
research on the NDN platform. It was initially based on `Mini-CCNx <https://github.com/chesteve/mn-ccnx>`_ which was a fork of `Mininet <https://github.com/mininet/mininet>`_. Mini-NDN uses the NDN libraries, NFD, NLSR, and tools released by the `NDN project <http://named-data.net/codebase/platform/>`_ to emulate an NDN network on a single system.
The first release of Mini-NDN is developed by members of the NSF-sponsored NDN project team.
Mini-NDN is open to contribution from the public.
.. image:: minindnnet.svg
License
_______
Mini-NDN is open and free software licensed under the GPL 3.0 license. Mini-NDN is free to all
users and developers. For more information about licensing details and limitations,
please refer to COPYING.md.
Feedback/Mailing List
_____________________
Bug reports and feedback are highly appreciated and can be made through our
`Redmine site <http://redmine.named-data.net/projects/mini-ndn>`_ and the
`mini-ndn mailing list <http://www.lists.cs.ucla.edu/mailman/listinfo/mini-ndn>`_.
Video
_____
.. raw:: html
<div id="video-container" class="col-md-6 ">
<p>Mini-NDN (content maybe outdated)</p>
<iframe width="600" height="345" src="https://www.youtube.com/embed/UxHPqaUwefg" frameborder="0" allowfullscreen=""></iframe>
</div>
+126
View File
@@ -0,0 +1,126 @@
<svg width="692" height="380" xmlns="http://www.w3.org/2000/svg">
<metadata id="metadata7">image/svg+xml</metadata>
<g>
<title>background</title>
<rect fill="none" id="canvas_background" height="382" width="694" y="-1" x="-1"/>
</g>
<g>
<title>Layer 1</title>
<g stroke="null" id="g3790">
<rect stroke="#000000" fill="#ffffff" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" id="rect2985" width="680.84682" height="350.443392" x="4.962804" y="5.773119" rx="0.324652"/>
<path stroke="#000000" fill="none" stroke-miterlimit="4" d="m4,175.828501l681.727736,1.357954" id="path3770"/>
</g>
<rect stroke="#000000" fill="#e3dedb" stroke-width="0.99538" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-dashoffset="0" rx="2.988095" y="176.111777" x="5.140841" height="180.524655" width="680.312936" id="rect3813"/>
<rect stroke="#000000" fill="#ffffff" stroke-width="1.602133" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-dasharray="4.80639973, 4.80639973" stroke-dashoffset="0" ry="8.582684" rx="7.476771" y="44.78072" x="55.492192" height="195.219243" width="148.366914" id="rect3764"/>
<rect stroke="#000000" fill="#ffffff" stroke-width="1.638042" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-dasharray="4.9141253, 4.9141253" stroke-dashoffset="0" id="rect3772" width="155.115252" height="195.190135" x="270.220868" y="46.153231" rx="7.816845" ry="8.581405"/>
<rect stroke="#000000" fill="#ffffff" stroke-width="1.602133" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-dasharray="4.80639973, 4.80639973" stroke-dashoffset="0" ry="8.582684" rx="7.476771" y="45.459696" x="489.86568" height="195.219243" width="148.366914" id="rect3774"/>
<text transform="matrix(1.0192718802397343,0,0,0.9115536073383187,-2.8313337784806336,-12.183034089773187) " font-size="16.005802px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3776" y="392.709737" x="551.171304" xml:space="preserve">
<tspan stroke="null" font-weight="normal" y="398.194877" x="552.152396" id="tspan3778">Kernel Space</tspan>
</text>
<text transform="matrix(1.0524848569125234,0,0,0.8827879284304422,-52.30106698198968,-77.5201889102731) " font-size="14.180006px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="601.466013" y="108.524983" id="text3782">
<tspan stroke="null" font-weight="normal" id="tspan3784" x="602.416145" y="114.188857">User Space</tspan>
</text>
<path stroke="#000000" fill="none" stroke-width="1px" id="path3796" d="m488.56554,176.773764c1.782236,0.480113 1.527628,0.360085 1.527628,0.360085"/>
<rect stroke="#000000" fill="#ffffff" stroke-width="0.649807" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-dashoffset="0" rx="0.838801" y="202.851471" x="84.255138" height="26.434283" width="94.537572" id="rect3815"/>
<rect stroke="#000000" fill="#ffffff" stroke-width="0.792138" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-dashoffset="0" id="rect3817" width="131.339764" height="28.275376" x="282.077514" y="201.912133" rx="1.165334"/>
<path stroke="#000000" fill="none" stroke-width="0.865499px" id="path3823" d="m347.74739,201.086282l0,28.351986"/>
<text transform="matrix(0.7776670647796514,0,0,1.19475416519067,-52.30106724263901,-77.52018902784596) " font-size="12.623897px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="434.634023" y="248.956571" id="text3835">
<tspan stroke="null" font-size="15.579311px" font-weight="bold" font-family="Monospace" x="435.91992" y="253.141532" id="tspan3837">n2-eth0</tspan>
</text>
<text transform="matrix(0.9031157255303414,0,0,1.0287949657006918,-2.8313337284492768,-13.069358400177762) " font-size="13.163442px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="110.835751" y="225.210496" id="text3863">
<tspan stroke="null" font-size="16.245171px" font-weight="bold" font-family="Monospace" x="111.943029" y="230.070551" id="tspan3865">n1-eth0</tspan>
</text>
<path stroke="#000000" fill="none" stroke-width="0.992521px" id="path3887" d="m131.263954,229.882774l0,67.221296l176.555867,-0.960307l1.337531,-65.300682"/>
<rect stroke="#000000" fill="#ffffff" stroke-width="0.676601" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-dashoffset="0" id="rect3891" width="95.679394" height="28.317195" x="515.346399" y="202.85306" rx="0.848932"/>
<path stroke="#000000" fill="none" stroke-width="0.992521px" d="m383.833251,230.842992l0,67.221296l176.555867,-0.960307l1.337531,-65.300682" id="path3897"/>
<text transform="matrix(0.9778213687833123,0,0,0.9501950205038839,-52.301066914088324,-76.5370021990862) " font-size="16.459864px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="164.136782" y="409.888383" id="text3907">
<tspan stroke="null" id="tspan3915" x="165.159464" y="415.15046">isolated point to point link</tspan>
</text>
<text transform="matrix(0.9778213687833123,0,0,0.9501950205038839,-52.301066914088324,-76.5370021990862) " font-size="16.459864px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3919" y="409.573373" x="429.378262" xml:space="preserve">
<tspan stroke="null" y="414.83545" x="430.400944" id="tspan3921">isolated point to point link</tspan>
</text>
<text transform="matrix(0.9778213687833123,0,0,0.9501950205038839,-52.301066914088324,-76.5370021990862) " font-size="16.459864px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3923" y="428.078233" x="194.615642" xml:space="preserve">
<tspan stroke="null" font-weight="bold" y="433.34031" x="195.638324" id="tspan3925">(eg: 1Mbps, 10ms)</tspan>
</text>
<text transform="matrix(0.9778213687833123,0,0,0.9501950205038839,-52.301066914088324,-76.5370021990862) " font-size="16.459864px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3927" y="409.888383" x="164.136782" xml:space="preserve">
<tspan stroke="null" y="415.15046" x="165.159464" id="tspan3929">Isolated point to point link</tspan>
</text>
<text transform="matrix(0.9778213687833123,0,0,0.9501950205038839,-52.301066914088324,-76.5370021990862) " font-size="16.459864px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="429.378262" y="409.573373" id="text3931">
<tspan stroke="null" id="tspan3933" x="430.400944" y="414.83545">Isolated point to point link</tspan>
</text>
<text transform="matrix(0.877827228897152,0,0,1.0584326041598764,-53.30106731891522,-78.4233265445007) " font-size="13.706223px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3935" y="282.545218" x="661.482605" xml:space="preserve">
<tspan stroke="null" font-size="16.915024px" font-weight="bold" font-family="Monospace" id="tspan3937" y="287.269185" x="662.621781">n3-eth0</tspan>
</text>
<text transform="matrix(0.7776670647796514,0,0,1.19475416519067,-52.30106724263901,-77.52018902784596) " font-size="12.623897px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3939" y="248.297391" x="520.751053" xml:space="preserve">
<tspan stroke="null" font-size="15.579311px" font-weight="bold" font-family="Monospace" id="tspan3941" y="252.482352" x="522.03695">n2-eth1</tspan>
</text>
<text transform="matrix(0.8745385143393076,0,0,1.0624128521471832,-2.8313338199928846,-14.069358364146652) " font-size="16.205975px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3943" y="80.648481" x="141.655977" xml:space="preserve">
<tspan stroke="null" font-size="20px" font-weight="bold" font-family="Monospace" id="tspan3945" y="85.354749" x="142.799437">n1</tspan>
</text>
<text transform="matrix(0.8745385143393076,0,0,1.0624128521471832,-2.8313338199928846,-14.069358364146652) " font-size="16.205975px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="385.430517" y="78.840861" id="text3955">
<tspan stroke="null" font-size="20px" font-weight="bold" font-family="Monospace" x="386.573977" y="83.547129" id="tspan3957">n2</tspan>
</text>
<text transform="matrix(0.8745385143393076,0,0,1.0624128521471832,-2.8313338199928846,-14.069358364146652) " font-size="16.205975px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3959" y="79.181231" x="632.310457" xml:space="preserve">
<tspan stroke="null" font-size="20px" font-weight="bold" font-family="Monospace" id="tspan3961" y="83.887499" x="633.453917">n3</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="125.371536" y="171.060971" id="text3967">
<tspan stroke="null" font-weight="normal" id="tspan3969" x="126.421253" y="176.187525">(NDN Container)</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3979" y="170.076461" x="352.011746" xml:space="preserve">
<tspan stroke="null" font-weight="normal" y="175.203015" x="353.061463" id="tspan3981">(NDN Container)</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="580.077396" y="169.091931" id="text3983">
<tspan stroke="null" font-weight="normal" id="tspan3985" x="581.127113" y="174.218485">(NDN Container)</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3987" y="193.704961" x="123.946116" xml:space="preserve">
<tspan stroke="null" font-weight="bold" y="198.831515" x="124.995833" id="tspan3989">NFD</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="140.791686" y="208.664491" id="text3991">
<tspan stroke="null" font-weight="normal" id="tspan3993" x="141.841403" y="213.791045">n1.sock</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="123.946116" y="225.286191" id="text3995">
<tspan stroke="null" font-weight="bold" id="tspan3997" x="124.995833" y="230.412745">NLSR</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text3999" y="240.245731" x="138.385176" xml:space="preserve">
<tspan stroke="null" font-weight="normal" y="245.372285" x="139.434893" id="tspan4001">%C1.Router/n1</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="352.011746" y="191.735901" id="text4003">
<tspan stroke="null" font-weight="bold" id="tspan4005" x="353.061463" y="196.862455">NFD</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text4007" y="206.695431" x="366.450896" xml:space="preserve">
<tspan stroke="null" font-weight="normal" y="211.821985" x="367.500613" id="tspan4009">n2.sock</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text4011" y="223.317141" x="352.011746" xml:space="preserve">
<tspan stroke="null" font-weight="bold" y="228.443695" x="353.061463" id="tspan4013">NLSR</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="366.450896" y="238.276671" id="text4015">
<tspan stroke="null" font-weight="normal" id="tspan4017" x="367.500613" y="243.403225">%C1.Router/n2</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text4019" y="190.751371" x="582.928226" xml:space="preserve">
<tspan stroke="null" font-weight="bold" y="195.877925" x="583.977943" id="tspan4021">NFD</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="599.773686" y="205.710911" id="text4023">
<tspan stroke="null" font-weight="normal" id="tspan4025" x="600.823403" y="210.837465">n3.sock</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="582.928226" y="222.332611" id="text4027">
<tspan stroke="null" font-weight="bold" id="tspan4029" x="583.977943" y="227.459165">NLSR</tspan>
</text>
<text transform="matrix(0.9526376792163275,0,0,0.9753141035001042,-53.30106707952308,-77.42332645354041) " font-size="14.959435px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text4031" y="237.292141" x="597.367186" xml:space="preserve">
<tspan stroke="null" font-weight="normal" y="242.418695" x="598.416903" id="tspan4033">%C1.Router/n3</tspan>
</text>
<text transform="matrix(0.9778213687833123,0,0,0.9501950205038839,-52.301066914088324,-76.5370021990862) " font-size="16.459864px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text4035" y="102.475413" x="322.701992" xml:space="preserve">
<tspan stroke="null" y="107.73749" x="323.724674" id="tspan4037">Isolated NDN nodes</tspan>
</text>
<text transform="matrix(0.935021961689298,0,0,0.9936889310882339,-2.9798247609055646,-12.086171479984756) " font-size="11.279781px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="75.549398" y="206.131281" id="text4039">
<tspan stroke="null" id="tspan4041" x="76.618892" y="211.163037">Private network space</tspan>
</text>
<text transform="matrix(0.935021961689298,0,0,0.9936889310882339,-2.9798247609055646,-12.086171479984756) " font-size="11.279781px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" id="text4043" y="206.946991" x="308.474828" xml:space="preserve">
<tspan stroke="null" y="211.978747" x="309.544322" id="tspan4045">Private network space</tspan>
</text>
<text transform="matrix(0.935021961689298,0,0,0.9936889310882339,-2.9798247609055646,-12.086171479984756) " font-size="11.279781px" font-style="normal" font-weight="normal" fill="#000000" font-family="Sans" xml:space="preserve" x="540.174348" y="206.131281" id="text4047">
<tspan stroke="null" id="tspan4049" x="541.243842" y="211.163037">Private network space</tspan>
</text>
<text xml:space="preserve" text-anchor="start" font-family="Helvetica,Arial,sans-serif" font-size="15px" id="svg_1" y="377" x="203.5" stroke-width="null" stroke="null" fill="#333">Figure: Relationship between Minindn and Mininet</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

+286
View File
@@ -0,0 +1,286 @@
Release Notes
=============
Mini-NDN version 0.6.0 (Major changes since version 0.5.0)
----------------------------------------------------------
**Breaking Changes**:
- Rewrite install script (`issue: 4630 <https://redmine.named-data.net/issues/4630>`__)
- Set dependency versions: PPA, git repository & commit
- Separate download and build+install steps
- Don't reinstall package if it's already installed
- More details `here <https://github.com/named-data/mini-ndn/blob/master/docs/install.rst>`__
- `Note: <https://redmine.named-data.net/issues/5161>`__ We have dropped support for python 2, the latest Mini-NDN requires at least python 3.0
**New features**:
- Update Mini-NDN codebase with Mini-NDN-Wifi code (`issue: 4858 <https://redmine.named-data.net/issues/4858>`__)
- Provide pre-built Mini-NDN Vagrant box and Docker container
- Added several new examples:
- consumer/producer
- ndnping
- traffic generator
- catchunks/putchunks
- Allow for creation of net object without topology (`issue: 5162 <https://redmine.named-data.net/issues/5162>`__)
**Improvements and Bug Fixes**:
- Support running NDN applications on mixed topologies (`issue: 5160 <https://redmine.named-data.net/issues/5160>`__)
- Support route addition using face-id in `Nfdc` helper (`issue: 5130 <https://redmine.named-data.net/issues/5130>`__)
- Add wrapper for `ndnpingserver` and fix passing the Mininet host object as a prefix on ndnpingclient
- Show status of route calculation in `NdnRoutingHelper`
- Incorporate changes of `NDNPing` Class (wrapper of pingserver and pingclient) in the examples
- Support simple topology files with no additional parameters
Mini-NDN version 0.5.0 (Major changes since version 0.4.0)
----------------------------------------------------------
**Breaking Changes**:
- `Mini-NDN re-design <https://redmine.named-data.net/issues/5062>`__: simple and robust design with better quality, control, and more consistency with Mininet
**New features**:
- Add a script to generate up-to-date NDN testbed topologies for Mini-NDN
- Add Mini-NDN utility application for PCAP logging
- Add NDN routing helper to compute centralized LS and HR routes
- Add routing helper to allow IP communication in experiments
- Add startup experiments for NLSR and current testbed topology
- Move the NDNPing wrapper method to a helper class
- Create a helper class to provide a wrapper around ``nfdc``
**Improvements and Bug Fixes**:
- Change workDir and resultDir to be class attribute
- Quiet apt install for Vagrant
- Fix route computation bug in ``ndn_routing_helper``
- Fix overwriting of existing prefixes in ``ndn_routing_helper``
- Move log files to resultDir after evaluation finishes
- Check for duplicate HR coordinates in the topology file
- Check PSync integration and add a tests case for it
- Bug fixes in nfdc and experiments
- Added functionality to check Mini-NDN dependencies
- Parser fix to avoid an infinite loop
- Allow use of NFD and NLSR PPA with Mini-NDN
- Remove arbitrary arguments in favor of parsing arguments from experiment files
- Auto-complete command-line arguments
- Add option to set CS size
- Adjust to use ndn-cxx logging
Mini-NDN version 0.4.0 (changes since version 0.3.0)
----------------------------------------------------
Release date: January 10, 2018
**New features**:
- Use SIGQUIT to quit Mini-NDN, SIGINT to kill programs
- Use Infoedit to edit NFD and NLSR configuration files
- Use nlsr.conf installed in the system
- Provide a Vagrantfile to setup Mini-NDN and NDN
- Provide option to disable NLSR
- Provide an option to run NLSR in dry-run mode
- Add option to specify whether to use TCP or UDP face in nlsr.conf
- Add option to specify arbitrary arguments to use in experiments
- Include a single option to install Mini-NDN and all the dependencies
**Bug fixes**:
- Fix "key does not exist error" after NLSR starts
- Update install.sh to call ldconfig after installing ChronoSync
- Add hyperbolic coordinates to default topology
**Misc changes**:
- Add an experiment to test nlsrc
- Create faces in NFD for each neighbor in NLSR
- Update to latest ndn-cxx
- Use /tmp/minindn folder as default work dir instead of /tmp
Mini-NDN version 0.3.0 (changes since version 0.2.0)
----------------------------------------------------
Release date: March 3, 2017
**New features**:
- Mini-NDN cluster edition
- New experiments for making NLSR testing easier
**Bug fixes**:
- Set site name correctly
- Install missing certificates in NLSR security config
- Fix quitting of NLSR due to key not found error
**Misc changes**:
- Removed nlsr.conf file, generate it within the code
- Use argparse instead of deprecated optparse
- Update security config section for NLSR
- Change mininet prompt to mini-ndn
- Set network name at one place
- Update install.sh script to install openssl
- Update install.sh script to install cryptopp from package instead of
compiling from source
- Update install.sh to clean build folder every time to get rid of
removed files such as old experiments
- Fix old code - use net.hosts instead of storing hosts in a variable
- Use nfdc instead of deprecated nfd-status
Mini-NDN version 0.2.0 (changes since version 0.1.1)
----------------------------------------------------
Release date: August 18, 2016
**New features**:
- Automatic security configuration for NLSR
- Use /usr/local/etc/ndn/nfd.conf as default config file for NFD
- Class to monitor /proc/$PID/stat file for PID
- Mini-NDN exits gracefully on SIGINT and non-convergence
- Faster Mini-NDN install script - does not do apt-get update everytime
- NLSR is launched with explicit config file for easier process
identification
- Add and update more documentation
**Bug fixes**:
- NFD is killed correctly on exit
- Best route strategy is set correctly
Mini-NDN version 0.1.1 (changes since version 0.1.0)
----------------------------------------------------
Release date: November 4, 2015
**New features**:
- Use nfd.conf.sample from currently installed NFD
- Add working directory option to allow execution environment outside
of /tmp
- Add results directory option to store experiment results after
completion
- Add support for switches in GUI and configuration file
- Add failNode and recoverNode methods to Experiment class
- Add most connected node (MCN) failure experiment
- Add option to specify percentage of nodes pinged
**Code changes**:
- Refactor program options into container class
- Remove unused "FIB Entries" option from NDN host options
**Bug fixes**:
- Abort start up if experiment name is invalid
- Restart pings after recovery in failure experiment
Mini-NDN version 0.1.0 (initial release)
----------------------------------------
Release date: July 15, 2015
Mini-NDN is a lightweight networking emulation tool that enables
testing, experimentation, and research on the NDN platform. Based on
Mininet, Mini-NDN uses the NDN libraries, NFD, NLSR, and tools released
by the `NDN project <http://named-data.net/codebase/platform/>`__ to
emulate an NDN network on a single system.
**Included features**:
- Run a complete NDN network on a single system
- Automatic configuration of NLSR to provide a routable NDN network
- Supports user created NDN applications
- Create a topology using the included Mini-NDN Edit GUI application
- Allows individual configuration of NFD and NLSR parameters for each
node
- Provides an experiment management framework for easy creation of
custom networking experiments
- Uses a simple topology file format to define hosts, links, and
configuration values
- Configure network link parameters including bandwidth, delay, and
loss rate
- Includes a pre-configured topology file to replicate the NDN testbed
+18
View File
@@ -0,0 +1,18 @@
Video Tutorials
===============
Maybe outdated since version 0.5.0.
.. raw:: html
<div id="video-container" class="col-md-6 ">
<p>Mini-NDN Demo at ACM, 2017</p>
<iframe width="400" height="230" src="https://www.youtube.com/embed/xYRPHZe18o0" frameborder="0" allowfullscreen=""></iframe>
</div>
.. raw:: html
<div id="video-container" class="col-md-6 "">
<p>Mini-NDN Overview </p>
<iframe width="400" height="230" src="https://www.youtube.com/embed/Da7t8yBWzv0" frameborder="0" allowfullscreen="">
</div>
-119
View File
@@ -1,119 +0,0 @@
Mininet Examples
========================================================
These examples are intended to help you get started using
Mininet's Python API.
========================================================
#### baresshd.py:
This example uses Mininet's medium-level API to create an sshd
process running in a namespace. Doesn't use OpenFlow.
#### consoles.py:
This example creates a grid of console windows, one for each node,
and allows interaction with and monitoring of each console, including
graphical monitoring.
#### controllers.py:
This example creates a network with multiple controllers, by
using a custom `Switch()` subclass.
#### controllers2.py:
This example creates a network with multiple controllers by
creating an empty network, adding nodes to it, and manually
starting the switches.
#### controlnet.py:
This examples shows how you can model the control network as well
as the data network, by actually creating two Mininet objects.
#### cpu.py:
This example tests iperf bandwidth for varying CPU limits.
#### emptynet.py:
This example demonstrates creating an empty network (i.e. with no
topology object) and adding nodes to it.
#### hwintf.py:
This example shows how to add an interface (for example a real
hardware interface) to a network after the network is created.
#### limit.py:
This example shows how to use link and CPU limits.
#### linearbandwidth.py:
This example shows how to create a custom topology programatically
by subclassing Topo, and how to run a series of tests on it.
#### miniedit.py:
This example demonstrates creating a network via a graphical editor.
#### multiping.py:
This example demonstrates one method for
monitoring output from multiple hosts, using `node.monitor()`.
#### multipoll.py:
This example demonstrates monitoring output files from multiple hosts.
#### multitest.py:
This example creates a network and runs multiple tests on it.
#### nat.py:
This example shows how to connect a Mininet network to the Internet
using NAT. It also answers the eternal question "why can't I ping
`google.com`?"
#### popen.py:
This example monitors a number of hosts using `host.popen()` and
`pmonitor()`.
#### popenpoll.py:
This example demonstrates monitoring output from multiple hosts using
the `node.popen()` interface (which returns `Popen` objects) and `pmonitor()`.
#### scratchnet.py, scratchnetuser.py:
These two examples demonstrate how to create a network by using the lowest-
level Mininet functions. Generally the higher-level API is easier to use,
but scratchnet shows what is going on behind the scenes.
#### simpleperf.py:
A simple example of configuring network and CPU bandwidth limits.
#### sshd.py:
This example shows how to run an `sshd` process in each host, allowing
you to log in via `ssh`. This requires connecting the Mininet data network
to an interface in the root namespace (generaly the control network
already lives in the root namespace, so it does not need to be explicitly
connected.)
#### tree1024.py:
This example attempts to create a 1024-host network, and then runs the
CLI on it. It may run into scalability limits, depending on available
memory and `sysctl` configuration (see `INSTALL`.)
#### treeping64.py:
This example creates a 64-host tree network, and attempts to check full
connectivity using `ping`, for different switch/datapath types.
-4
View File
@@ -1,4 +0,0 @@
"""
Mininet Examples
See README for details
"""
-37
View File
@@ -1,37 +0,0 @@
#!/usr/bin/python
"This example doesn't use OpenFlow, but attempts to run sshd in a namespace."
import sys
from mininet.node import Host
from mininet.util import ensureRoot
ensureRoot()
print "*** Creating nodes"
h1 = Host( 'h1' )
root = Host( 'root', inNamespace=False )
print "*** Creating links"
h1.linkTo( root )
print h1
print "*** Configuring nodes"
h1.setIP( '10.0.0.1', 8 )
root.setIP( '10.0.0.2', 8 )
print "*** Creating banner file"
f = open( '/tmp/%s.banner' % h1.name, 'w' )
f.write( 'Welcome to %s at %s\n' % ( h1.name, h1.IP() ) )
f.close()
print "*** Running sshd"
cmd = '/usr/sbin/sshd -o UseDNS=no -u0 -o "Banner /tmp/%s.banner"' % h1.name
# add arguments from the command line
if len( sys.argv ) > 1:
cmd += ' ' + ' '.join( sys.argv[ 1: ] )
h1.cmd( cmd )
print "*** You may now ssh into", h1.name, "at", h1.IP()
-197
View File
@@ -1,197 +0,0 @@
#!/usr/bin/python
"""
bind.py: Bind mount prototype
This creates hosts with private directories as desired.
"""
from mininet.net import Mininet
from mininet.node import Host
from mininet.cli import CLI
from mininet.util import errFail, quietRun, errRun
from mininet.topo import SingleSwitchTopo
from mininet.log import setLogLevel, info, debug
from os.path import realpath
from functools import partial
# Utility functions for unmounting a tree
MNRUNDIR = realpath( '/var/run/mn' )
def mountPoints():
"Return list of mounted file systems"
mtab, _err, _ret = errFail( 'cat /proc/mounts' )
lines = mtab.split( '\n' )
mounts = []
for line in lines:
if not line:
continue
fields = line.split( ' ')
mount = fields[ 1 ]
mounts.append( mount )
return mounts
def unmountAll( rootdir=MNRUNDIR ):
"Unmount all mounts under a directory tree"
rootdir = realpath( rootdir )
# Find all mounts below rootdir
# This is subtle because /foo is not
# a parent of /foot
dirslash = rootdir + '/'
mounts = [ m for m in mountPoints()
if m == dir or m.find( dirslash ) == 0 ]
# Unmount them from bottom to top
mounts.sort( reverse=True )
for mount in mounts:
debug( 'Unmounting', mount, '\n' )
_out, err, code = errRun( 'umount', mount )
if code != 0:
info( '*** Warning: failed to umount', mount, '\n' )
info( err )
class HostWithPrivateDirs( Host ):
"Host with private directories"
mnRunDir = MNRUNDIR
def __init__(self, name, *args, **kwargs ):
"""privateDirs: list of private directories
remounts: dirs to remount
unmount: unmount dirs in cleanup? (True)
Note: if unmount is False, you must call unmountAll()
manually."""
self.privateDirs = kwargs.pop( 'privateDirs', [] )
self.remounts = kwargs.pop( 'remounts', [] )
self.unmount = kwargs.pop( 'unmount', True )
Host.__init__( self, name, *args, **kwargs )
self.rundir = '%s/%s' % ( self.mnRunDir, name )
self.root, self.private = None, None # set in createBindMounts
if self.privateDirs:
self.privateDirs = [ realpath( d ) for d in self.privateDirs ]
self.createBindMounts()
# These should run in the namespace before we chroot,
# in order to put the right entries in /etc/mtab
# Eventually this will allow a local pid space
# Now we chroot and cd to wherever we were before.
pwd = self.cmd( 'pwd' ).strip()
self.sendCmd( 'exec chroot', self.root, 'bash -ms mininet:'
+ self.name )
self.waiting = False
self.cmd( 'cd', pwd )
# In order for many utilities to work,
# we need to remount /proc and /sys
self.cmd( 'mount /proc' )
self.cmd( 'mount /sys' )
def mountPrivateDirs( self ):
"Create and bind mount private dirs"
for dir_ in self.privateDirs:
privateDir = self.private + dir_
errFail( 'mkdir -p ' + privateDir )
mountPoint = self.root + dir_
errFail( 'mount -B %s %s' %
( privateDir, mountPoint) )
def mountDirs( self, dirs ):
"Mount a list of directories"
for dir_ in dirs:
mountpoint = self.root + dir_
errFail( 'mount -B %s %s' %
( dir_, mountpoint ) )
@classmethod
def findRemounts( cls, fstypes=None ):
"""Identify mount points in /proc/mounts to remount
fstypes: file system types to match"""
if fstypes is None:
fstypes = [ 'nfs' ]
dirs = quietRun( 'cat /proc/mounts' ).strip().split( '\n' )
remounts = []
for dir_ in dirs:
line = dir_.split()
mountpoint, fstype = line[ 1 ], line[ 2 ]
# Don't re-remount directories!!!
if mountpoint.find( cls.mnRunDir ) == 0:
continue
if fstype in fstypes:
remounts.append( mountpoint )
return remounts
def createBindMounts( self ):
"""Create a chroot directory structure,
with self.privateDirs as private dirs"""
errFail( 'mkdir -p '+ self.rundir )
unmountAll( self.rundir )
# Create /root and /private directories
self.root = self.rundir + '/root'
self.private = self.rundir + '/private'
errFail( 'mkdir -p ' + self.root )
errFail( 'mkdir -p ' + self.private )
# Recursively mount / in private doort
# note we'll remount /sys and /proc later
errFail( 'mount -B / ' + self.root )
self.mountDirs( self.remounts )
self.mountPrivateDirs()
def unmountBindMounts( self ):
"Unmount all of our bind mounts"
unmountAll( self.rundir )
def popen( self, *args, **kwargs ):
"Popen with chroot support"
chroot = kwargs.pop( 'chroot', True )
mncmd = kwargs.get( 'mncmd',
[ 'mnexec', '-a', str( self.pid ) ] )
if chroot:
mncmd = [ 'chroot', self.root ] + mncmd
kwargs[ 'mncmd' ] = mncmd
return Host.popen( self, *args, **kwargs )
def cleanup( self ):
"""Clean up, then unmount bind mounts
unmount: actually unmount bind mounts?"""
# Wait for process to actually terminate
self.shell.wait()
Host.cleanup( self )
if self.unmount:
self.unmountBindMounts()
errFail( 'rmdir ' + self.root )
# Convenience aliases
findRemounts = HostWithPrivateDirs.findRemounts
# Sample usage
def testHostWithPrivateDirs():
"Test bind mounts"
topo = SingleSwitchTopo( 10 )
remounts = findRemounts( fstypes=[ 'nfs' ] )
privateDirs = [ '/var/log', '/var/run' ]
host = partial( HostWithPrivateDirs, remounts=remounts,
privateDirs=privateDirs, unmount=False )
net = Mininet( topo=topo, host=host )
net.start()
info( 'Private Directories:', privateDirs, '\n' )
CLI( net )
net.stop()
# We do this all at once to save a bit of time
info( 'Unmounting host bind mounts...\n' )
unmountAll()
if __name__ == '__main__':
unmountAll()
setLogLevel( 'info' )
testHostWithPrivateDirs()
info( 'Done.\n')
+95
View File
@@ -0,0 +1,95 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2021, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
"""
This example demonstrates the functionality of the ndncatchunks and ndnputchunks. There are
programs to transfer a file as Data segments in NDN.
https://github.com/named-data/ndn-tools/tree/master/tools/chunks.
"""
from time import sleep
import subprocess
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
def sendFile(node, prefix, file):
"""
Publish a file using ndnputchunks
:parma mininet.node.Host node: mininet node object
:param string prefix: prefix to publish the chunks of the file
:param string file: file to publish
"""
info ("File published:", file)
cmd = 'ndnputchunks {}/{} < {} > putchunks.log 2>&1 &'.format(prefix, "fname", file)
node.cmd(cmd)
# Sleep for appropriate time based on the file size
sleep(5)
def receiveFile(node, prefix, filename):
"""
Fetch a file using ndncatchunks
:parma mininet.node.Host node: mininet node object
:param string prefix: producer's prefix under which the file the published
:param string file: name given to the file that will be received
"""
info ("Fething file: ", filename)
cmd = 'ndncatchunks {}/{} > {} 2> catchunks.log &'.format(prefix, "fname", filename)
node.cmd(cmd)
if __name__ == '__main__':
setLogLevel('info')
# Create a test file to publish
testFile = "/tmp/test-chunks"
cmd = 'echo "demonstrate file transfer using catchunks and putchunks" > {}'.format(testFile)
subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).communicate()
Minindn.cleanUp()
Minindn.verifyDependencies()
ndn = Minindn()
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr)
sleep(70)
# Default topology is used in this experiment "/topologies/default-topology.conf"
# lets make node "a" as a producer node, and node "c" as a conumer node
producer = ndn.net['a']
producerPrefix = "/test-producer" # prefix under which the file will be published
consumer = ndn.net['c']
# Advertise the producer prefix to the network
producer.cmd('nlsrc advertise {}'.format(producerPrefix))
sleep (5) # sleep for routing convergence.
sendFile(producer, producerPrefix, testFile)
receiveFile(consumer, producerPrefix, "test-chunks")
MiniNDNCLI(ndn.net)
ndn.stop()
-466
View File
@@ -1,466 +0,0 @@
#!/usr/bin/python
"""
consoles.py: bring up a bunch of miniature consoles on a virtual network
This demo shows how to monitor a set of nodes by using
Node's monitor() and Tkinter's createfilehandler().
We monitor nodes in a couple of ways:
- First, each individual node is monitored, and its output is added
to its console window
- Second, each time a console window gets iperf output, it is parsed
and accumulated. Once we have output for all consoles, a bar is
added to the bandwidth graph.
The consoles also support limited interaction:
- Pressing "return" in a console will send a command to it
- Pressing the console's title button will open up an xterm
Bob Lantz, April 2010
"""
import re
from Tkinter import Frame, Button, Label, Text, Scrollbar, Canvas, Wm, READABLE
from mininet.log import setLogLevel
from mininet.topolib import TreeNet
from mininet.term import makeTerms, cleanUpScreens
from mininet.util import quietRun
class Console( Frame ):
"A simple console on a host."
def __init__( self, parent, net, node, height=10, width=32, title='Node' ):
Frame.__init__( self, parent )
self.net = net
self.node = node
self.prompt = node.name + '# '
self.height, self.width, self.title = height, width, title
# Initialize widget styles
self.buttonStyle = { 'font': 'Monaco 7' }
self.textStyle = {
'font': 'Monaco 7',
'bg': 'black',
'fg': 'green',
'width': self.width,
'height': self.height,
'relief': 'sunken',
'insertbackground': 'green',
'highlightcolor': 'green',
'selectforeground': 'black',
'selectbackground': 'green'
}
# Set up widgets
self.text = self.makeWidgets( )
self.bindEvents()
self.sendCmd( 'export TERM=dumb' )
self.outputHook = None
def makeWidgets( self ):
"Make a label, a text area, and a scroll bar."
def newTerm( net=self.net, node=self.node, title=self.title ):
"Pop up a new terminal window for a node."
net.terms += makeTerms( [ node ], title )
label = Button( self, text=self.node.name, command=newTerm,
**self.buttonStyle )
label.pack( side='top', fill='x' )
text = Text( self, wrap='word', **self.textStyle )
ybar = Scrollbar( self, orient='vertical', width=7,
command=text.yview )
text.configure( yscrollcommand=ybar.set )
text.pack( side='left', expand=True, fill='both' )
ybar.pack( side='right', fill='y' )
return text
def bindEvents( self ):
"Bind keyboard and file events."
# The text widget handles regular key presses, but we
# use special handlers for the following:
self.text.bind( '<Return>', self.handleReturn )
self.text.bind( '<Control-c>', self.handleInt )
self.text.bind( '<KeyPress>', self.handleKey )
# This is not well-documented, but it is the correct
# way to trigger a file event handler from Tk's
# event loop!
self.tk.createfilehandler( self.node.stdout, READABLE,
self.handleReadable )
# We're not a terminal (yet?), so we ignore the following
# control characters other than [\b\n\r]
ignoreChars = re.compile( r'[\x00-\x07\x09\x0b\x0c\x0e-\x1f]+' )
def append( self, text ):
"Append something to our text frame."
text = self.ignoreChars.sub( '', text )
self.text.insert( 'end', text )
self.text.mark_set( 'insert', 'end' )
self.text.see( 'insert' )
outputHook = lambda x, y: True # make pylint happier
if self.outputHook:
outputHook = self.outputHook
outputHook( self, text )
def handleKey( self, event ):
"If it's an interactive command, send it to the node."
char = event.char
if self.node.waiting:
self.node.write( char )
def handleReturn( self, event ):
"Handle a carriage return."
cmd = self.text.get( 'insert linestart', 'insert lineend' )
# Send it immediately, if "interactive" command
if self.node.waiting:
self.node.write( event.char )
return
# Otherwise send the whole line to the shell
pos = cmd.find( self.prompt )
if pos >= 0:
cmd = cmd[ pos + len( self.prompt ): ]
self.sendCmd( cmd )
# Callback ignores event
def handleInt( self, _event=None ):
"Handle control-c."
self.node.sendInt()
def sendCmd( self, cmd ):
"Send a command to our node."
if not self.node.waiting:
self.node.sendCmd( cmd )
def handleReadable( self, _fds, timeoutms=None ):
"Handle file readable event."
data = self.node.monitor( timeoutms )
self.append( data )
if not self.node.waiting:
# Print prompt
self.append( self.prompt )
def waiting( self ):
"Are we waiting for output?"
return self.node.waiting
def waitOutput( self ):
"Wait for any remaining output."
while self.node.waiting:
# A bit of a trade-off here...
self.handleReadable( self, timeoutms=1000)
self.update()
def clear( self ):
"Clear all of our text."
self.text.delete( '1.0', 'end' )
class Graph( Frame ):
"Graph that we can add bars to over time."
def __init__( self, parent=None, bg = 'white', gheight=200, gwidth=500,
barwidth=10, ymax=3.5,):
Frame.__init__( self, parent )
self.bg = bg
self.gheight = gheight
self.gwidth = gwidth
self.barwidth = barwidth
self.ymax = float( ymax )
self.xpos = 0
# Create everything
self.title, self.scale, self.graph = self.createWidgets()
self.updateScrollRegions()
self.yview( 'moveto', '1.0' )
def createScale( self ):
"Create a and return a new canvas with scale markers."
height = float( self.gheight )
width = 25
ymax = self.ymax
scale = Canvas( self, width=width, height=height,
background=self.bg )
opts = { 'fill': 'red' }
# Draw scale line
scale.create_line( width - 1, height, width - 1, 0, **opts )
# Draw ticks and numbers
for y in range( 0, int( ymax + 1 ) ):
ypos = height * (1 - float( y ) / ymax )
scale.create_line( width, ypos, width - 10, ypos, **opts )
scale.create_text( 10, ypos, text=str( y ), **opts )
return scale
def updateScrollRegions( self ):
"Update graph and scale scroll regions."
ofs = 20
height = self.gheight + ofs
self.graph.configure( scrollregion=( 0, -ofs,
self.xpos * self.barwidth, height ) )
self.scale.configure( scrollregion=( 0, -ofs, 0, height ) )
def yview( self, *args ):
"Scroll both scale and graph."
self.graph.yview( *args )
self.scale.yview( *args )
def createWidgets( self ):
"Create initial widget set."
# Objects
title = Label( self, text='Bandwidth (Gb/s)', bg=self.bg )
width = self.gwidth
height = self.gheight
scale = self.createScale()
graph = Canvas( self, width=width, height=height, background=self.bg)
xbar = Scrollbar( self, orient='horizontal', command=graph.xview )
ybar = Scrollbar( self, orient='vertical', command=self.yview )
graph.configure( xscrollcommand=xbar.set, yscrollcommand=ybar.set,
scrollregion=(0, 0, width, height ) )
scale.configure( yscrollcommand=ybar.set )
# Layout
title.grid( row=0, columnspan=3, sticky='new')
scale.grid( row=1, column=0, sticky='nsew' )
graph.grid( row=1, column=1, sticky='nsew' )
ybar.grid( row=1, column=2, sticky='ns' )
xbar.grid( row=2, column=0, columnspan=2, sticky='ew' )
self.rowconfigure( 1, weight=1 )
self.columnconfigure( 1, weight=1 )
return title, scale, graph
def addBar( self, yval ):
"Add a new bar to our graph."
percent = yval / self.ymax
c = self.graph
x0 = self.xpos * self.barwidth
x1 = x0 + self.barwidth
y0 = self.gheight
y1 = ( 1 - percent ) * self.gheight
c.create_rectangle( x0, y0, x1, y1, fill='green' )
self.xpos += 1
self.updateScrollRegions()
self.graph.xview( 'moveto', '1.0' )
def clear( self ):
"Clear graph contents."
self.graph.delete( 'all' )
self.xpos = 0
def test( self ):
"Add a bar for testing purposes."
ms = 1000
if self.xpos < 10:
self.addBar( self.xpos / 10 * self.ymax )
self.after( ms, self.test )
def setTitle( self, text ):
"Set graph title"
self.title.configure( text=text, font='Helvetica 9 bold' )
class ConsoleApp( Frame ):
"Simple Tk consoles for Mininet."
menuStyle = { 'font': 'Geneva 7 bold' }
def __init__( self, net, parent=None, width=4 ):
Frame.__init__( self, parent )
self.top = self.winfo_toplevel()
self.top.title( 'Mininet' )
self.net = net
self.menubar = self.createMenuBar()
cframe = self.cframe = Frame( self )
self.consoles = {} # consoles themselves
titles = {
'hosts': 'Host',
'switches': 'Switch',
'controllers': 'Controller'
}
for name in titles:
nodes = getattr( net, name )
frame, consoles = self.createConsoles(
cframe, nodes, width, titles[ name ] )
self.consoles[ name ] = Object( frame=frame, consoles=consoles )
self.selected = None
self.select( 'hosts' )
self.cframe.pack( expand=True, fill='both' )
cleanUpScreens()
# Close window gracefully
Wm.wm_protocol( self.top, name='WM_DELETE_WINDOW', func=self.quit )
# Initialize graph
graph = Graph( cframe )
self.consoles[ 'graph' ] = Object( frame=graph, consoles=[ graph ] )
self.graph = graph
self.graphVisible = False
self.updates = 0
self.hostCount = len( self.consoles[ 'hosts' ].consoles )
self.bw = 0
self.pack( expand=True, fill='both' )
def updateGraph( self, _console, output ):
"Update our graph."
m = re.search( r'(\d+.?\d*) ([KMG]?bits)/sec', output )
if not m:
return
val, units = float( m.group( 1 ) ), m.group( 2 )
#convert to Gbps
if units[0] == 'M':
val *= 10 ** -3
elif units[0] == 'K':
val *= 10 ** -6
elif units[0] == 'b':
val *= 10 ** -9
self.updates += 1
self.bw += val
if self.updates >= self.hostCount:
self.graph.addBar( self.bw )
self.bw = 0
self.updates = 0
def setOutputHook( self, fn=None, consoles=None ):
"Register fn as output hook [on specific consoles.]"
if consoles is None:
consoles = self.consoles[ 'hosts' ].consoles
for console in consoles:
console.outputHook = fn
def createConsoles( self, parent, nodes, width, title ):
"Create a grid of consoles in a frame."
f = Frame( parent )
# Create consoles
consoles = []
index = 0
for node in nodes:
console = Console( f, self.net, node, title=title )
consoles.append( console )
row = index / width
column = index % width
console.grid( row=row, column=column, sticky='nsew' )
index += 1
f.rowconfigure( row, weight=1 )
f.columnconfigure( column, weight=1 )
return f, consoles
def select( self, groupName ):
"Select a group of consoles to display."
if self.selected is not None:
self.selected.frame.pack_forget()
self.selected = self.consoles[ groupName ]
self.selected.frame.pack( expand=True, fill='both' )
def createMenuBar( self ):
"Create and return a menu (really button) bar."
f = Frame( self )
buttons = [
( 'Hosts', lambda: self.select( 'hosts' ) ),
( 'Switches', lambda: self.select( 'switches' ) ),
( 'Controllers', lambda: self.select( 'controllers' ) ),
( 'Graph', lambda: self.select( 'graph' ) ),
( 'Ping', self.ping ),
( 'Iperf', self.iperf ),
( 'Interrupt', self.stop ),
( 'Clear', self.clear ),
( 'Quit', self.quit )
]
for name, cmd in buttons:
b = Button( f, text=name, command=cmd, **self.menuStyle )
b.pack( side='left' )
f.pack( padx=4, pady=4, fill='x' )
return f
def clear( self ):
"Clear selection."
for console in self.selected.consoles:
console.clear()
def waiting( self, consoles=None ):
"Are any of our hosts waiting for output?"
if consoles is None:
consoles = self.consoles[ 'hosts' ].consoles
for console in consoles:
if console.waiting():
return True
return False
def ping( self ):
"Tell each host to ping the next one."
consoles = self.consoles[ 'hosts' ].consoles
if self.waiting( consoles ):
return
count = len( consoles )
i = 0
for console in consoles:
i = ( i + 1 ) % count
ip = consoles[ i ].node.IP()
console.sendCmd( 'ping ' + ip )
def iperf( self ):
"Tell each host to iperf to the next one."
consoles = self.consoles[ 'hosts' ].consoles
if self.waiting( consoles ):
return
count = len( consoles )
self.setOutputHook( self.updateGraph )
for console in consoles:
# Sometimes iperf -sD doesn't return,
# so we run it in the background instead
console.node.cmd( 'iperf -s &' )
i = 0
for console in consoles:
i = ( i + 1 ) % count
ip = consoles[ i ].node.IP()
console.sendCmd( 'iperf -t 99999 -i 1 -c ' + ip )
def stop( self, wait=True ):
"Interrupt all hosts."
consoles = self.consoles[ 'hosts' ].consoles
for console in consoles:
console.handleInt()
if wait:
for console in consoles:
console.waitOutput()
self.setOutputHook( None )
# Shut down any iperfs that might still be running
quietRun( 'killall -9 iperf' )
def quit( self ):
"Stop everything and quit."
self.stop( wait=False)
Frame.quit( self )
# Make it easier to construct and assign objects
def assign( obj, **kwargs ):
"Set a bunch of fields in an object."
obj.__dict__.update( kwargs )
class Object( object ):
"Generic object you can stuff junk into."
def __init__( self, **kwargs ):
assign( self, **kwargs )
if __name__ == '__main__':
setLogLevel( 'info' )
network = TreeNet( depth=2, fanout=4 )
network.start()
app = ConsoleApp( network, width=4 )
app.mainloop()
network.stop()
+70
View File
@@ -0,0 +1,70 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2021, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from time import sleep
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
"""
This example demonstrates a basic consumer-producer using Mini-NDN. It uses ndnpeek and ndnpoke as
a consumer and a producer respectively. If you want to build your own consumer/producer program, you
can take help from here: https://github.com/named-data/ndn-cxx/tree/master/examples and
here: https://github.com/dulalsaurab/multicast-supression-ndn/tree/main/ndn-src/consumer-producer
"""
if __name__ == '__main__':
setLogLevel('info')
Minindn.cleanUp()
Minindn.verifyDependencies()
ndn = Minindn()
ndn.start()
info('Starting nfd and nlsr on nodes')
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr)
sleep(90)
# Default topology is used in this experiment "/topologies/default-topology.conf"
# lets make node "a" as a producer node, and node "c" as a consumer node
producer = ndn.net['a']
consumer = ndn.net['c']
# start producer
producerPrefix = "/example"
producer.cmd('nlsrc advertise {}'.format(producerPrefix))
sleep(5) # sleep for routing convergence
# Make sure that basic consumer/producer example are compiled and installed in the system
info('Starting consumer and producer application')
producer.cmd("echo 'HELLO WORLD' | ndnpoke {} &> producer.log &".format(producerPrefix))
consumer.cmd("ndnpeek -p {} &> consumer.log &".format(producerPrefix))
MiniNDNCLI(ndn.net)
ndn.stop()
-36
View File
@@ -1,36 +0,0 @@
#!/usr/bin/python
"""
Create a network where different switches are connected to
different controllers, by creating a custom Switch() subclass.
"""
from mininet.net import Mininet
from mininet.node import OVSSwitch, Controller, RemoteController
from mininet.topolib import TreeTopo
from mininet.log import setLogLevel
from mininet.cli import CLI
setLogLevel( 'info' )
# Two local and one "external" controller (which is actually c0)
# Ignore the warning message that the remote isn't (yet) running
c0 = Controller( 'c0', port=6633 )
c1 = Controller( 'c1', port=6634 )
c2 = RemoteController( 'c2', ip='127.0.0.1' )
cmap = { 's1': c0, 's2': c1, 's3': c2 }
class MultiSwitch( OVSSwitch ):
"Custom Switch() subclass that connects to different controllers"
def start( self, controllers ):
return OVSSwitch.start( self, [ cmap[ self.name ] ] )
topo = TreeTopo( depth=2, fanout=2 )
net = Mininet( topo=topo, switch=MultiSwitch, build=False )
for c in [ c0, c1 ]:
net.addController(c)
net.build()
net.start()
CLI( net )
net.stop()
-61
View File
@@ -1,61 +0,0 @@
#!/usr/bin/python
"""
This example creates a multi-controller network from semi-scratch by
using the net.add*() API and manually starting the switches and controllers.
This is the "mid-level" API, which is an alternative to the "high-level"
Topo() API which supports parametrized topology classes.
Note that one could also create a custom switch class and pass it into
the Mininet() constructor.
"""
from mininet.net import Mininet
from mininet.node import Controller, OVSSwitch
from mininet.cli import CLI
from mininet.log import setLogLevel
def multiControllerNet():
"Create a network from semi-scratch with multiple controllers."
net = Mininet( controller=Controller, switch=OVSSwitch, build=False )
print "*** Creating (reference) controllers"
c1 = net.addController( 'c1', port=6633 )
c2 = net.addController( 'c2', port=6634 )
print "*** Creating switches"
s1 = net.addSwitch( 's1' )
s2 = net.addSwitch( 's2' )
print "*** Creating hosts"
hosts1 = [ net.addHost( 'h%d' % n ) for n in 3, 4 ]
hosts2 = [ net.addHost( 'h%d' % n ) for n in 5, 6 ]
print "*** Creating links"
for h in hosts1:
net.addLink( s1, h )
for h in hosts2:
net.addLink( s2, h )
net.addLink( s1, s2 )
print "*** Starting network"
net.build()
c1.start()
c2.start()
s1.start( [ c1 ] )
s2.start( [ c2 ] )
print "*** Testing network"
net.pingAll()
print "*** Running CLI"
CLI( net )
print "*** Stopping network"
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' ) # for CLI output
multiControllerNet()
-151
View File
@@ -1,151 +0,0 @@
#!/usr/bin/python
"""
controlnet.py: Mininet with a custom control network
We create two Mininet() networks, a control network
and a data network, running four DataControllers on the
control network to control the data network.
Since we're using UserSwitch on the data network,
it should correctly fail over to a backup controller.
We also use a Mininet Facade to talk to both the
control and data networks from a single CLI.
"""
from functools import partial
from mininet.net import Mininet
from mininet.node import Controller, UserSwitch
from mininet.cli import CLI
from mininet.topo import Topo
from mininet.topolib import TreeTopo
from mininet.log import setLogLevel, info
# Some minor hacks
class DataController( Controller ):
"""Data Network Controller.
patched to avoid checkListening error"""
def checkListening( self ):
"Ignore spurious error"
pass
class MininetFacade( object ):
"""Mininet object facade that allows a single CLI to
talk to one or more networks"""
def __init__( self, net, *args, **kwargs ):
"""Create MininetFacade object.
net: Primary Mininet object
args: unnamed networks passed as arguments
kwargs: named networks passed as arguments"""
self.net = net
self.nets = [ net ] + list( args ) + kwargs.values()
self.nameToNet = kwargs
self.nameToNet['net'] = net
def __getattr__( self, name ):
"returns attribute from Primary Mininet object"
return getattr( self.net, name )
def __getitem__( self, key ):
"returns primary/named networks or node from any net"
#search kwargs for net named key
if key in self.nameToNet:
return self.nameToNet[ key ]
#search each net for node named key
for net in self.nets:
if key in net:
return net[ key ]
def __iter__( self ):
"Iterate through all nodes in all Mininet objects"
for net in self.nets:
for node in net:
yield node
def __len__( self ):
"returns aggregate number of nodes in all nets"
count = 0
for net in self.nets:
count += len(net)
return count
def __contains__( self, key ):
"returns True if node is a member of any net"
return key in self.keys()
def keys( self ):
"returns a list of all node names in all networks"
return list( self )
def values( self ):
"returns a list of all nodes in all networks"
return [ self[ key ] for key in self ]
def items( self ):
"returns (key,value) tuple list for every node in all networks"
return zip( self.keys(), self.values() )
# A real control network!
class ControlNetwork( Topo ):
"Control Network Topology"
def __init__( self, n, dataController=DataController, **kwargs ):
"""n: number of data network controller nodes
dataController: class for data network controllers"""
Topo.__init__( self, **kwargs )
# Connect everything to a single switch
cs0 = self.addSwitch( 'cs0' )
# Add hosts which will serve as data network controllers
for i in range( 0, n ):
c = self.addHost( 'c%s' % i, cls=dataController,
inNamespace=True )
self.addLink( c, cs0 )
# Connect switch to root namespace so that data network
# switches will be able to talk to us
root = self.addHost( 'root', inNamespace=False )
self.addLink( root, cs0 )
# Make it Happen!!
def run():
"Create control and data networks, and invoke the CLI"
info( '* Creating Control Network\n' )
ctopo = ControlNetwork( n=4, dataController=DataController )
cnet = Mininet( topo=ctopo, ipBase='192.168.123.0/24', controller=None )
info( '* Adding Control Network Controller\n')
cnet.addController( 'cc0', controller=Controller )
info( '* Starting Control Network\n')
cnet.start()
info( '* Creating Data Network\n' )
topo = TreeTopo( depth=2, fanout=2 )
# UserSwitch so we can easily test failover
sw = partial( UserSwitch, opts='--inactivity-probe=1 --max-backoff=1' )
net = Mininet( topo=topo, switch=sw, controller=None )
info( '* Adding Controllers to Data Network\n' )
for host in cnet.hosts:
if isinstance(host, Controller):
net.addController( host )
info( '* Starting Data Network\n')
net.start()
mn = MininetFacade( net, cnet=cnet )
CLI( mn )
info( '* Stopping Data Network\n' )
net.stop()
info( '* Stopping Control Network\n' )
cnet.stop()
if __name__ == '__main__':
setLogLevel( 'info' )
run()
-81
View File
@@ -1,81 +0,0 @@
#!/usr/bin/python
"""
cpu.py: test iperf bandwidth for varying cpu limits
"""
from mininet.net import Mininet
from mininet.node import CPULimitedHost
from mininet.topolib import TreeTopo
from mininet.util import custom
from mininet.log import setLogLevel, output
from time import sleep
def waitListening(client, server, port):
"Wait until server is listening on port"
if not client.cmd('which telnet'):
raise Exception('Could not find telnet')
cmd = ('sh -c "echo A | telnet -e A %s %s"' %
(server.IP(), port))
while 'Connected' not in client.cmd(cmd):
output('waiting for', server,
'to listen on port', port, '\n')
sleep(.5)
def bwtest( cpuLimits, period_us=100000, seconds=5 ):
"""Example/test of link and CPU bandwidth limits
cpu: cpu limit as fraction of overall CPU time"""
topo = TreeTopo( depth=1, fanout=2 )
results = {}
for sched in 'rt', 'cfs':
print '*** Testing with', sched, 'bandwidth limiting'
for cpu in cpuLimits:
host = custom( CPULimitedHost, sched=sched,
period_us=period_us,
cpu=cpu )
net = Mininet( topo=topo, host=host )
net.start()
net.pingAll()
hosts = [ net.getNodeByName( h ) for h in topo.hosts() ]
client, server = hosts[ 0 ], hosts[ -1 ]
server.cmd( 'iperf -s -p 5001 &' )
waitListening( client, server, 5001 )
result = client.cmd( 'iperf -yc -t %s -c %s' % (
seconds, server.IP() ) ).split( ',' )
bps = float( result[ -1 ] )
server.cmdPrint( 'kill %iperf' )
net.stop()
updated = results.get( sched, [] )
updated += [ ( cpu, bps ) ]
results[ sched ] = updated
return results
def dump( results ):
"Dump results"
fmt = '%s\t%s\t%s'
print
print fmt % ( 'sched', 'cpu', 'client MB/s' )
print
for sched in sorted( results.keys() ):
entries = results[ sched ]
for cpu, bps in entries:
pct = '%.2f%%' % ( cpu * 100 )
mbps = bps / 1e6
print fmt % ( sched, pct, mbps )
if __name__ == '__main__':
setLogLevel( 'info' )
limits = [ .45, .4, .3, .2, .1 ]
out = bwtest( limits )
dump( out )
-44
View File
@@ -1,44 +0,0 @@
#!/usr/bin/python
"""
This example shows how to create an empty Mininet object
(without a topology object) and add nodes to it manually.
"""
from mininet.net import Mininet
from mininet.node import Controller
from mininet.cli import CLI
from mininet.log import setLogLevel, info
def emptyNet():
"Create an empty network and add nodes to it."
net = Mininet( controller=Controller )
info( '*** Adding controller\n' )
net.addController( 'c0' )
info( '*** Adding hosts\n' )
h1 = net.addHost( 'h1', ip='10.0.0.1' )
h2 = net.addHost( 'h2', ip='10.0.0.2' )
info( '*** Adding switch\n' )
s3 = net.addSwitch( 's3' )
info( '*** Creating links\n' )
net.addLink( h1, s3 )
net.addLink( h2, s3 )
info( '*** Starting network\n')
net.start()
info( '*** Running CLI\n' )
CLI( net )
info( '*** Stopping network' )
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' )
emptyNet()
-51
View File
@@ -1,51 +0,0 @@
#!/usr/bin/python
"""
This example shows how to add an interface (for example a real
hardware interface) to a network after the network is created.
"""
import re, sys
from mininet.cli import CLI
from mininet.log import setLogLevel, info, error
from mininet.net import Mininet
from mininet.link import Intf
from mininet.topolib import TreeTopo
from mininet.util import quietRun
def checkIntf( intf ):
"Make sure intf exists and is not configured."
if ( ' %s:' % intf ) not in quietRun( 'ip link show' ):
error( 'Error:', intf, 'does not exist!\n' )
exit( 1 )
ips = re.findall( r'\d+\.\d+\.\d+\.\d+', quietRun( 'ifconfig ' + intf ) )
if ips:
error( 'Error:', intf, 'has an IP address,'
'and is probably in use!\n' )
exit( 1 )
if __name__ == '__main__':
setLogLevel( 'info' )
# try to get hw intf from the command line; by default, use eth1
intfName = sys.argv[ 1 ] if len( sys.argv ) > 1 else 'eth1'
info( '*** Connecting to hw intf: %s' % intfName )
info( '*** Checking', intfName, '\n' )
checkIntf( intfName )
info( '*** Creating network\n' )
net = Mininet( topo=TreeTopo( depth=1, fanout=2 ) )
switch = net.switches[ 0 ]
info( '*** Adding hardware interface', intfName, 'to switch',
switch.name, '\n' )
_intf = Intf( intfName, node=switch )
info( '*** Note: you may need to reconfigure the interfaces for '
'the Mininet hosts:\n', net.hosts, '\n' )
net.start()
CLI( net )
net.stop()
+62
View File
@@ -0,0 +1,62 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2020, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from minindn.helpers.ip_routing_helper import IPRoutingHelper
"""
This scenario demonstrates the functionality of the IPRoutingHelper. First, the routing helper
calculates and configures routes between all nodes and then calls the `pingAll` command to
demonstrate that all nodes are reachable.
Successful experiments end with: `*** Results: 0% dropped`
To demonstrate the IPRoutingHelper in more complex scenarios, consider starting the experiment with
the Geant-Topology (topologies/geant.conf).
"""
if __name__ == '__main__':
setLogLevel('info')
Minindn.cleanUp()
Minindn.verifyDependencies()
ndn = Minindn()
ndn.start()
info('Starting NFD on nodes\n')
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
info('Starting NLSR on nodes\n')
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr)
# Calculate all routes for IP routing
IPRoutingHelper.calcAllRoutes(ndn.net)
info("IP routes configured, start ping\n")
ndn.net.pingAll()
ndn.stop()
-53
View File
@@ -1,53 +0,0 @@
#!/usr/bin/python
"""
limit.py: example of using link and CPU limits
"""
from mininet.net import Mininet
from mininet.link import TCIntf
from mininet.node import CPULimitedHost
from mininet.topolib import TreeTopo
from mininet.util import custom
from mininet.log import setLogLevel
def testLinkLimit( net, bw ):
"Run bandwidth limit test"
print '*** Testing network %.2f Mbps bandwidth limit' % bw
net.iperf( )
def limit( bw=10, cpu=.1 ):
"""Example/test of link and CPU bandwidth limits
bw: interface bandwidth limit in Mbps
cpu: cpu limit as fraction of overall CPU time"""
intf = custom( TCIntf, bw=bw )
myTopo = TreeTopo( depth=1, fanout=2 )
for sched in 'rt', 'cfs':
print '*** Testing with', sched, 'bandwidth limiting'
host = custom( CPULimitedHost, sched=sched, cpu=cpu )
net = Mininet( topo=myTopo, intf=intf, host=host )
net.start()
testLinkLimit( net, bw=bw )
net.runCpuLimitTest( cpu=cpu )
net.stop()
def verySimpleLimit( bw=150 ):
"Absurdly simple limiting test"
intf = custom( TCIntf, bw=bw )
net = Mininet( intf=intf )
h1, h2 = net.addHost( 'h1' ), net.addHost( 'h2' )
net.addLink( h1, h2 )
net.start()
net.pingAll()
net.iperf()
h1.cmdPrint( 'tc -s qdisc ls dev', h1.defaultIntf() )
h2.cmdPrint( 'tc -d class show dev', h2.defaultIntf() )
h1.cmdPrint( 'tc -s qdisc ls dev', h1.defaultIntf() )
h2.cmdPrint( 'tc -d class show dev', h2.defaultIntf() )
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' )
limit()
-110
View File
@@ -1,110 +0,0 @@
#!/usr/bin/python
"""
Test bandwidth (using iperf) on linear networks of varying size,
using both kernel and user datapaths.
We construct a network of N hosts and N-1 switches, connected as follows:
h1 <-> s1 <-> s2 .. sN-1
| | |
h2 h3 hN
WARNING: by default, the reference controller only supports 16
switches, so this test WILL NOT WORK unless you have recompiled
your controller to support 100 switches (or more.)
In addition to testing the bandwidth across varying numbers
of switches, this example demonstrates:
- creating a custom topology, LinearTestTopo
- using the ping() and iperf() tests from Mininet()
- testing both the kernel and user switches
"""
from mininet.net import Mininet
from mininet.node import UserSwitch, OVSKernelSwitch
from mininet.topo import Topo
from mininet.log import lg
from mininet.util import irange
import sys
flush = sys.stdout.flush
class LinearTestTopo( Topo ):
"Topology for a string of N hosts and N-1 switches."
def __init__( self, N, **params ):
# Initialize topology
Topo.__init__( self, **params )
# Create switches and hosts
hosts = [ self.addHost( 'h%s' % h )
for h in irange( 1, N ) ]
switches = [ self.addSwitch( 's%s' % s )
for s in irange( 1, N - 1 ) ]
# Wire up switches
last = None
for switch in switches:
if last:
self.addLink( last, switch )
last = switch
# Wire up hosts
self.addLink( hosts[ 0 ], switches[ 0 ] )
for host, switch in zip( hosts[ 1: ], switches ):
self.addLink( host, switch )
def linearBandwidthTest( lengths ):
"Check bandwidth at various lengths along a switch chain."
results = {}
switchCount = max( lengths )
hostCount = switchCount + 1
switches = { 'reference user': UserSwitch,
'Open vSwitch kernel': OVSKernelSwitch }
topo = LinearTestTopo( hostCount )
for datapath in switches.keys():
print "*** testing", datapath, "datapath"
Switch = switches[ datapath ]
results[ datapath ] = []
net = Mininet( topo=topo, switch=Switch )
net.start()
print "*** testing basic connectivity"
for n in lengths:
net.ping( [ net.hosts[ 0 ], net.hosts[ n ] ] )
print "*** testing bandwidth"
for n in lengths:
src, dst = net.hosts[ 0 ], net.hosts[ n ]
print "testing", src.name, "<->", dst.name,
bandwidth = net.iperf( [ src, dst ] )
print bandwidth
flush()
results[ datapath ] += [ ( n, bandwidth ) ]
net.stop()
for datapath in switches.keys():
print
print "*** Linear network results for", datapath, "datapath:"
print
result = results[ datapath ]
print "SwitchCount\tiperf Results"
for switchCount, bandwidth in result:
print switchCount, '\t\t',
print bandwidth[ 0 ], 'server, ', bandwidth[ 1 ], 'client'
print
print
if __name__ == '__main__':
lg.setLogLevel( 'info' )
sizes = [ 1, 10, 20, 40, 60, 80, 100 ]
print "*** Running linearBandwidthTest", sizes
linearBandwidthTest( sizes )
-704
View File
@@ -1,704 +0,0 @@
#!/usr/bin/python
"""
MiniEdit: a simple network editor for Mininet
This is a simple demonstration of how one might build a
GUI application using Mininet as the network model.
Development version - not entirely functional!
Bob Lantz, April 2010
"""
from Tkinter import Frame, Button, Label, Scrollbar, Canvas
from Tkinter import Menu, BitmapImage, PhotoImage, Wm, Toplevel
# someday: from ttk import *
from mininet.log import setLogLevel
from mininet.net import Mininet
from mininet.util import ipStr
from mininet.term import makeTerm, cleanUpScreens
class MiniEdit( Frame ):
"A simple network editor for Mininet."
def __init__( self, parent=None, cheight=200, cwidth=500 ):
Frame.__init__( self, parent )
self.action = None
self.appName = 'MiniEdit'
# Style
self.font = ( 'Geneva', 9 )
self.smallFont = ( 'Geneva', 7 )
self.bg = 'white'
# Title
self.top = self.winfo_toplevel()
self.top.title( self.appName )
# Menu bar
self.createMenubar()
# Editing canvas
self.cheight, self.cwidth = cheight, cwidth
self.cframe, self.canvas = self.createCanvas()
# Toolbar
self.images = miniEditImages()
self.buttons = {}
self.active = None
self.tools = ( 'Select', 'Host', 'Switch', 'Link' )
self.customColors = { 'Switch': 'darkGreen', 'Host': 'blue' }
self.toolbar = self.createToolbar()
# Layout
self.toolbar.grid( column=0, row=0, sticky='nsew')
self.cframe.grid( column=1, row=0 )
self.columnconfigure( 1, weight=1 )
self.rowconfigure( 0, weight=1 )
self.pack( expand=True, fill='both' )
# About box
self.aboutBox = None
# Initialize node data
self.nodeBindings = self.createNodeBindings()
self.nodePrefixes = { 'Switch': 's', 'Host': 'h' }
self.widgetToItem = {}
self.itemToWidget = {}
# Initialize link tool
self.link = self.linkWidget = None
# Selection support
self.selection = None
# Keyboard bindings
self.bind( '<Control-q>', lambda event: self.quit() )
self.bind( '<KeyPress-Delete>', self.deleteSelection )
self.bind( '<KeyPress-BackSpace>', self.deleteSelection )
self.focus()
# Event handling initalization
self.linkx = self.linky = self.linkItem = None
self.lastSelection = None
# Model initialization
self.links = {}
self.nodeCount = 0
self.net = None
# Close window gracefully
Wm.wm_protocol( self.top, name='WM_DELETE_WINDOW', func=self.quit )
def quit( self ):
"Stop our network, if any, then quit."
self.stop()
Frame.quit( self )
def createMenubar( self ):
"Create our menu bar."
font = self.font
mbar = Menu( self.top, font=font )
self.top.configure( menu=mbar )
# Application menu
appMenu = Menu( mbar, tearoff=False )
mbar.add_cascade( label=self.appName, font=font, menu=appMenu )
appMenu.add_command( label='About MiniEdit', command=self.about,
font=font)
appMenu.add_separator()
appMenu.add_command( label='Quit', command=self.quit, font=font )
#fileMenu = Menu( mbar, tearoff=False )
#mbar.add_cascade( label="File", font=font, menu=fileMenu )
#fileMenu.add_command( label="Load...", font=font )
#fileMenu.add_separator()
#fileMenu.add_command( label="Save", font=font )
#fileMenu.add_separator()
#fileMenu.add_command( label="Print", font=font )
editMenu = Menu( mbar, tearoff=False )
mbar.add_cascade( label="Edit", font=font, menu=editMenu )
editMenu.add_command( label="Cut", font=font,
command=lambda: self.deleteSelection( None ) )
runMenu = Menu( mbar, tearoff=False )
mbar.add_cascade( label="Run", font=font, menu=runMenu )
runMenu.add_command( label="Run", font=font, command=self.doRun )
runMenu.add_command( label="Stop", font=font, command=self.doStop )
runMenu.add_separator()
runMenu.add_command( label='Xterm', font=font, command=self.xterm )
# Canvas
def createCanvas( self ):
"Create and return our scrolling canvas frame."
f = Frame( self )
canvas = Canvas( f, width=self.cwidth, height=self.cheight,
bg=self.bg )
# Scroll bars
xbar = Scrollbar( f, orient='horizontal', command=canvas.xview )
ybar = Scrollbar( f, orient='vertical', command=canvas.yview )
canvas.configure( xscrollcommand=xbar.set, yscrollcommand=ybar.set )
# Resize box
resize = Label( f, bg='white' )
# Layout
canvas.grid( row=0, column=1, sticky='nsew')
ybar.grid( row=0, column=2, sticky='ns')
xbar.grid( row=1, column=1, sticky='ew' )
resize.grid( row=1, column=2, sticky='nsew' )
# Resize behavior
f.rowconfigure( 0, weight=1 )
f.columnconfigure( 1, weight=1 )
f.grid( row=0, column=0, sticky='nsew' )
f.bind( '<Configure>', lambda event: self.updateScrollRegion() )
# Mouse bindings
canvas.bind( '<ButtonPress-1>', self.clickCanvas )
canvas.bind( '<B1-Motion>', self.dragCanvas )
canvas.bind( '<ButtonRelease-1>', self.releaseCanvas )
return f, canvas
def updateScrollRegion( self ):
"Update canvas scroll region to hold everything."
bbox = self.canvas.bbox( 'all' )
if bbox is not None:
self.canvas.configure( scrollregion=( 0, 0, bbox[ 2 ],
bbox[ 3 ] ) )
def canvasx( self, x_root ):
"Convert root x coordinate to canvas coordinate."
c = self.canvas
return c.canvasx( x_root ) - c.winfo_rootx()
def canvasy( self, y_root ):
"Convert root y coordinate to canvas coordinate."
c = self.canvas
return c.canvasy( y_root ) - c.winfo_rooty()
# Toolbar
def activate( self, toolName ):
"Activate a tool and press its button."
# Adjust button appearance
if self.active:
self.buttons[ self.active ].configure( relief='raised' )
self.buttons[ toolName ].configure( relief='sunken' )
# Activate dynamic bindings
self.active = toolName
def createToolbar( self ):
"Create and return our toolbar frame."
toolbar = Frame( self )
# Tools
for tool in self.tools:
cmd = ( lambda t=tool: self.activate( t ) )
b = Button( toolbar, text=tool, font=self.smallFont, command=cmd)
if tool in self.images:
b.config( height=35, image=self.images[ tool ] )
# b.config( compound='top' )
b.pack( fill='x' )
self.buttons[ tool ] = b
self.activate( self.tools[ 0 ] )
# Spacer
Label( toolbar, text='' ).pack()
# Commands
for cmd, color in [ ( 'Stop', 'darkRed' ), ( 'Run', 'darkGreen' ) ]:
doCmd = getattr( self, 'do' + cmd )
b = Button( toolbar, text=cmd, font=self.smallFont,
fg=color, command=doCmd )
b.pack( fill='x', side='bottom' )
return toolbar
def doRun( self ):
"Run command."
self.activate( 'Select' )
for tool in self.tools:
self.buttons[ tool ].config( state='disabled' )
self.start()
def doStop( self ):
"Stop command."
self.stop()
for tool in self.tools:
self.buttons[ tool ].config( state='normal' )
# Generic canvas handler
#
# We could have used bindtags, as in nodeIcon, but
# the dynamic approach used here
# may actually require less code. In any case, it's an
# interesting introspection-based alternative to bindtags.
def canvasHandle( self, eventName, event ):
"Generic canvas event handler"
if self.active is None:
return
toolName = self.active
handler = getattr( self, eventName + toolName, None )
if handler is not None:
handler( event )
def clickCanvas( self, event ):
"Canvas click handler."
self.canvasHandle( 'click', event )
def dragCanvas( self, event ):
"Canvas drag handler."
self.canvasHandle( 'drag', event )
def releaseCanvas( self, event ):
"Canvas mouse up handler."
self.canvasHandle( 'release', event )
# Currently the only items we can select directly are
# links. Nodes are handled by bindings in the node icon.
def findItem( self, x, y ):
"Find items at a location in our canvas."
items = self.canvas.find_overlapping( x, y, x, y )
if len( items ) == 0:
return None
else:
return items[ 0 ]
# Canvas bindings for Select, Host, Switch and Link tools
def clickSelect( self, event ):
"Select an item."
self.selectItem( self.findItem( event.x, event.y ) )
def deleteItem( self, item ):
"Delete an item."
# Don't delete while network is running
if self.buttons[ 'Select' ][ 'state' ] == 'disabled':
return
# Delete from model
if item in self.links:
self.deleteLink( item )
if item in self.itemToWidget:
self.deleteNode( item )
# Delete from view
self.canvas.delete( item )
def deleteSelection( self, _event ):
"Delete the selected item."
if self.selection is not None:
self.deleteItem( self.selection )
self.selectItem( None )
def nodeIcon( self, node, name ):
"Create a new node icon."
icon = Button( self.canvas, image=self.images[ node ],
text=name, compound='top' )
# Unfortunately bindtags wants a tuple
bindtags = [ str( self.nodeBindings ) ]
bindtags += list( icon.bindtags() )
icon.bindtags( tuple( bindtags ) )
return icon
def newNode( self, node, event ):
"Add a new node to our canvas."
c = self.canvas
x, y = c.canvasx( event.x ), c.canvasy( event.y )
self.nodeCount += 1
name = self.nodePrefixes[ node ] + str( self.nodeCount )
icon = self.nodeIcon( node, name )
item = self.canvas.create_window( x, y, anchor='c', window=icon,
tags=node )
self.widgetToItem[ icon ] = item
self.itemToWidget[ item ] = icon
self.selectItem( item )
icon.links = {}
def clickHost( self, event ):
"Add a new host to our canvas."
self.newNode( 'Host', event )
def clickSwitch( self, event ):
"Add a new switch to our canvas."
self.newNode( 'Switch', event )
def dragLink( self, event ):
"Drag a link's endpoint to another node."
if self.link is None:
return
# Since drag starts in widget, we use root coords
x = self.canvasx( event.x_root )
y = self.canvasy( event.y_root )
c = self.canvas
c.coords( self.link, self.linkx, self.linky, x, y )
def releaseLink( self, _event ):
"Give up on the current link."
if self.link is not None:
self.canvas.delete( self.link )
self.linkWidget = self.linkItem = self.link = None
# Generic node handlers
def createNodeBindings( self ):
"Create a set of bindings for nodes."
bindings = {
'<ButtonPress-1>': self.clickNode,
'<B1-Motion>': self.dragNode,
'<ButtonRelease-1>': self.releaseNode,
'<Enter>': self.enterNode,
'<Leave>': self.leaveNode,
'<Double-ButtonPress-1>': self.xterm
}
l = Label() # lightweight-ish owner for bindings
for event, binding in bindings.items():
l.bind( event, binding )
return l
def selectItem( self, item ):
"Select an item and remember old selection."
self.lastSelection = self.selection
self.selection = item
def enterNode( self, event ):
"Select node on entry."
self.selectNode( event )
def leaveNode( self, _event ):
"Restore old selection on exit."
self.selectItem( self.lastSelection )
def clickNode( self, event ):
"Node click handler."
if self.active is 'Link':
self.startLink( event )
else:
self.selectNode( event )
return 'break'
def dragNode( self, event ):
"Node drag handler."
if self.active is 'Link':
self.dragLink( event )
else:
self.dragNodeAround( event )
def releaseNode( self, event ):
"Node release handler."
if self.active is 'Link':
self.finishLink( event )
# Specific node handlers
def selectNode( self, event ):
"Select the node that was clicked on."
item = self.widgetToItem.get( event.widget, None )
self.selectItem( item )
def dragNodeAround( self, event ):
"Drag a node around on the canvas."
c = self.canvas
# Convert global to local coordinates;
# Necessary since x, y are widget-relative
x = self.canvasx( event.x_root )
y = self.canvasy( event.y_root )
w = event.widget
# Adjust node position
item = self.widgetToItem[ w ]
c.coords( item, x, y )
# Adjust link positions
for dest in w.links:
link = w.links[ dest ]
item = self.widgetToItem[ dest ]
x1, y1 = c.coords( item )
c.coords( link, x, y, x1, y1 )
def startLink( self, event ):
"Start a new link."
if event.widget not in self.widgetToItem:
# Didn't click on a node
return
w = event.widget
item = self.widgetToItem[ w ]
x, y = self.canvas.coords( item )
self.link = self.canvas.create_line( x, y, x, y, width=4,
fill='blue', tag='link' )
self.linkx, self.linky = x, y
self.linkWidget = w
self.linkItem = item
# Link bindings
# Selection still needs a bit of work overall
# Callbacks ignore event
def select( _event, link=self.link ):
"Select item on mouse entry."
self.selectItem( link )
def highlight( _event, link=self.link ):
"Highlight item on mouse entry."
# self.selectItem( link )
self.canvas.itemconfig( link, fill='green' )
def unhighlight( _event, link=self.link ):
"Unhighlight item on mouse exit."
self.canvas.itemconfig( link, fill='blue' )
# self.selectItem( None )
self.canvas.tag_bind( self.link, '<Enter>', highlight )
self.canvas.tag_bind( self.link, '<Leave>', unhighlight )
self.canvas.tag_bind( self.link, '<ButtonPress-1>', select )
def finishLink( self, event ):
"Finish creating a link"
if self.link is None:
return
source = self.linkWidget
c = self.canvas
# Since we dragged from the widget, use root coords
x, y = self.canvasx( event.x_root ), self.canvasy( event.y_root )
target = self.findItem( x, y )
dest = self.itemToWidget.get( target, None )
if ( source is None or dest is None or source == dest
or dest in source.links or source in dest.links ):
self.releaseLink( event )
return
# For now, don't allow hosts to be directly linked
stags = self.canvas.gettags( self.widgetToItem[ source ] )
dtags = self.canvas.gettags( target )
if 'Host' in stags and 'Host' in dtags:
self.releaseLink( event )
return
x, y = c.coords( target )
c.coords( self.link, self.linkx, self.linky, x, y )
self.addLink( source, dest )
# We're done
self.link = self.linkWidget = None
# Menu handlers
def about( self ):
"Display about box."
about = self.aboutBox
if about is None:
bg = 'white'
about = Toplevel( bg='white' )
about.title( 'About' )
info = self.appName + ': a simple network editor for MiniNet'
warning = 'Development version - not entirely functional!'
author = 'Bob Lantz <rlantz@cs>, April 2010'
line1 = Label( about, text=info, font='Helvetica 10 bold', bg=bg )
line2 = Label( about, text=warning, font='Helvetica 9', bg=bg )
line3 = Label( about, text=author, font='Helvetica 9', bg=bg )
line1.pack( padx=20, pady=10 )
line2.pack(pady=10 )
line3.pack(pady=10 )
hide = ( lambda about=about: about.withdraw() )
self.aboutBox = about
# Hide on close rather than destroying window
Wm.wm_protocol( about, name='WM_DELETE_WINDOW', func=hide )
# Show (existing) window
about.deiconify()
def createToolImages( self ):
"Create toolbar (and icon) images."
# Model interface
#
# Ultimately we will either want to use a topo or
# mininet object here, probably.
def addLink( self, source, dest ):
"Add link to model."
source.links[ dest ] = self.link
dest.links[ source ] = self.link
self.links[ self.link ] = ( source, dest )
def deleteLink( self, link ):
"Delete link from model."
pair = self.links.get( link, None )
if pair is not None:
source, dest = pair
del source.links[ dest ]
del dest.links[ source ]
if link is not None:
del self.links[ link ]
def deleteNode( self, item ):
"Delete node (and its links) from model."
widget = self.itemToWidget[ item ]
for link in widget.links.values():
# Delete from view and model
self.deleteItem( link )
del self.itemToWidget[ item ]
del self.widgetToItem[ widget ]
def build( self ):
"Build network based on our topology."
net = Mininet( topo=None )
# Make controller
net.addController( 'c0' )
# Make nodes
for widget in self.widgetToItem:
name = widget[ 'text' ]
tags = self.canvas.gettags( self.widgetToItem[ widget ] )
nodeNum = int( name[ 1: ] )
if 'Switch' in tags:
net.addSwitch( name )
elif 'Host' in tags:
#Generate IP adddress in the 10.0/8 block
ipAddr = ( 10 << 24 ) + nodeNum
net.addHost( name, ip=ipStr( ipAddr ) )
else:
raise Exception( "Cannot create mystery node: " + name )
# Make links
for link in self.links.values():
( src, dst ) = link
srcName, dstName = src[ 'text' ], dst[ 'text' ]
src, dst = net.nameToNode[ srcName ], net.nameToNode[ dstName ]
src.linkTo( dst )
# Build network (we have to do this separately at the moment )
net.build()
return net
def start( self ):
"Start network."
if self.net is None:
self.net = self.build()
self.net.start()
def stop( self ):
"Stop network."
if self.net is not None:
self.net.stop()
cleanUpScreens()
self.net = None
def xterm( self, _ignore=None ):
"Make an xterm when a button is pressed."
if ( self.selection is None or
self.net is None or
self.selection not in self.itemToWidget ):
return
name = self.itemToWidget[ self.selection ][ 'text' ]
if name not in self.net.nameToNode:
return
term = makeTerm( self.net.nameToNode[ name ], 'Host' )
self.net.terms += term
def miniEditImages():
"Create and return images for MiniEdit."
# Image data. Git will be unhappy. However, the alternative
# is to keep track of separate binary files, which is also
# unappealing.
return {
'Select': BitmapImage(
file='/usr/include/X11/bitmaps/left_ptr' ),
'Host': PhotoImage( data=r"""
R0lGODlhIAAYAPcAMf//////zP//mf//Zv//M///AP/M///MzP/M
mf/MZv/MM//MAP+Z//+ZzP+Zmf+ZZv+ZM/+ZAP9m//9mzP9mmf9m
Zv9mM/9mAP8z//8zzP8zmf8zZv8zM/8zAP8A//8AzP8Amf8AZv8A
M/8AAMz//8z/zMz/mcz/Zsz/M8z/AMzM/8zMzMzMmczMZszMM8zM
AMyZ/8yZzMyZmcyZZsyZM8yZAMxm/8xmzMxmmcxmZsxmM8xmAMwz
/8wzzMwzmcwzZswzM8wzAMwA/8wAzMwAmcwAZswAM8wAAJn//5n/
zJn/mZn/Zpn/M5n/AJnM/5nMzJnMmZnMZpnMM5nMAJmZ/5mZzJmZ
mZmZZpmZM5mZAJlm/5lmzJlmmZlmZplmM5lmAJkz/5kzzJkzmZkz
ZpkzM5kzAJkA/5kAzJkAmZkAZpkAM5kAAGb//2b/zGb/mWb/Zmb/
M2b/AGbM/2bMzGbMmWbMZmbMM2bMAGaZ/2aZzGaZmWaZZmaZM2aZ
AGZm/2ZmzGZmmWZmZmZmM2ZmAGYz/2YzzGYzmWYzZmYzM2YzAGYA
/2YAzGYAmWYAZmYAM2YAADP//zP/zDP/mTP/ZjP/MzP/ADPM/zPM
zDPMmTPMZjPMMzPMADOZ/zOZzDOZmTOZZjOZMzOZADNm/zNmzDNm
mTNmZjNmMzNmADMz/zMzzDMzmTMzZjMzMzMzADMA/zMAzDMAmTMA
ZjMAMzMAAAD//wD/zAD/mQD/ZgD/MwD/AADM/wDMzADMmQDMZgDM
MwDMAACZ/wCZzACZmQCZZgCZMwCZAABm/wBmzABmmQBmZgBmMwBm
AAAz/wAzzAAzmQAzZgAzMwAzAAAA/wAAzAAAmQAAZgAAM+4AAN0A
ALsAAKoAAIgAAHcAAFUAAEQAACIAABEAAADuAADdAAC7AACqAACI
AAB3AABVAABEAAAiAAARAAAA7gAA3QAAuwAAqgAAiAAAdwAAVQAA
RAAAIgAAEe7u7t3d3bu7u6qqqoiIiHd3d1VVVURERCIiIhEREQAA
ACH5BAEAAAAALAAAAAAgABgAAAiNAAH8G0iwoMGDCAcKTMiw4UBw
BPXVm0ixosWLFvVBHFjPoUeC9Tb+6/jRY0iQ/8iVbHiS40CVKxG2
HEkQZsyCM0mmvGkw50uePUV2tEnOZkyfQA8iTYpTKNOgKJ+C3AhO
p9SWVaVOfWj1KdauTL9q5UgVbFKsEjGqXVtP40NwcBnCjXtw7tx/
C8cSBBAQADs=
""" ),
'Switch': PhotoImage( data=r"""
R0lGODlhIAAYAPcAMf//////zP//mf//Zv//M///AP/M///MzP/M
mf/MZv/MM//MAP+Z//+ZzP+Zmf+ZZv+ZM/+ZAP9m//9mzP9mmf9m
Zv9mM/9mAP8z//8zzP8zmf8zZv8zM/8zAP8A//8AzP8Amf8AZv8A
M/8AAMz//8z/zMz/mcz/Zsz/M8z/AMzM/8zMzMzMmczMZszMM8zM
AMyZ/8yZzMyZmcyZZsyZM8yZAMxm/8xmzMxmmcxmZsxmM8xmAMwz
/8wzzMwzmcwzZswzM8wzAMwA/8wAzMwAmcwAZswAM8wAAJn//5n/
zJn/mZn/Zpn/M5n/AJnM/5nMzJnMmZnMZpnMM5nMAJmZ/5mZzJmZ
mZmZZpmZM5mZAJlm/5lmzJlmmZlmZplmM5lmAJkz/5kzzJkzmZkz
ZpkzM5kzAJkA/5kAzJkAmZkAZpkAM5kAAGb//2b/zGb/mWb/Zmb/
M2b/AGbM/2bMzGbMmWbMZmbMM2bMAGaZ/2aZzGaZmWaZZmaZM2aZ
AGZm/2ZmzGZmmWZmZmZmM2ZmAGYz/2YzzGYzmWYzZmYzM2YzAGYA
/2YAzGYAmWYAZmYAM2YAADP//zP/zDP/mTP/ZjP/MzP/ADPM/zPM
zDPMmTPMZjPMMzPMADOZ/zOZzDOZmTOZZjOZMzOZADNm/zNmzDNm
mTNmZjNmMzNmADMz/zMzzDMzmTMzZjMzMzMzADMA/zMAzDMAmTMA
ZjMAMzMAAAD//wD/zAD/mQD/ZgD/MwD/AADM/wDMzADMmQDMZgDM
MwDMAACZ/wCZzACZmQCZZgCZMwCZAABm/wBmzABmmQBmZgBmMwBm
AAAz/wAzzAAzmQAzZgAzMwAzAAAA/wAAzAAAmQAAZgAAM+4AAN0A
ALsAAKoAAIgAAHcAAFUAAEQAACIAABEAAADuAADdAAC7AACqAACI
AAB3AABVAABEAAAiAAARAAAA7gAA3QAAuwAAqgAAiAAAdwAAVQAA
RAAAIgAAEe7u7t3d3bu7u6qqqoiIiHd3d1VVVURERCIiIhEREQAA
ACH5BAEAAAAALAAAAAAgABgAAAhwAAEIHEiwoMGDCBMqXMiwocOH
ECNKnEixosWB3zJq3Mixo0eNAL7xG0mypMmTKPl9Cznyn8uWL/m5
/AeTpsyYI1eKlBnO5r+eLYHy9Ck0J8ubPmPOrMmUpM6UUKMa/Ui1
6saLWLNq3cq1q9evYB0GBAA7
""" ),
'Link': PhotoImage( data=r"""
R0lGODlhFgAWAPcAMf//////zP//mf//Zv//M///AP/M///MzP/M
mf/MZv/MM//MAP+Z//+ZzP+Zmf+ZZv+ZM/+ZAP9m//9mzP9mmf9m
Zv9mM/9mAP8z//8zzP8zmf8zZv8zM/8zAP8A//8AzP8Amf8AZv8A
M/8AAMz//8z/zMz/mcz/Zsz/M8z/AMzM/8zMzMzMmczMZszMM8zM
AMyZ/8yZzMyZmcyZZsyZM8yZAMxm/8xmzMxmmcxmZsxmM8xmAMwz
/8wzzMwzmcwzZswzM8wzAMwA/8wAzMwAmcwAZswAM8wAAJn//5n/
zJn/mZn/Zpn/M5n/AJnM/5nMzJnMmZnMZpnMM5nMAJmZ/5mZzJmZ
mZmZZpmZM5mZAJlm/5lmzJlmmZlmZplmM5lmAJkz/5kzzJkzmZkz
ZpkzM5kzAJkA/5kAzJkAmZkAZpkAM5kAAGb//2b/zGb/mWb/Zmb/
M2b/AGbM/2bMzGbMmWbMZmbMM2bMAGaZ/2aZzGaZmWaZZmaZM2aZ
AGZm/2ZmzGZmmWZmZmZmM2ZmAGYz/2YzzGYzmWYzZmYzM2YzAGYA
/2YAzGYAmWYAZmYAM2YAADP//zP/zDP/mTP/ZjP/MzP/ADPM/zPM
zDPMmTPMZjPMMzPMADOZ/zOZzDOZmTOZZjOZMzOZADNm/zNmzDNm
mTNmZjNmMzNmADMz/zMzzDMzmTMzZjMzMzMzADMA/zMAzDMAmTMA
ZjMAMzMAAAD//wD/zAD/mQD/ZgD/MwD/AADM/wDMzADMmQDMZgDM
MwDMAACZ/wCZzACZmQCZZgCZMwCZAABm/wBmzABmmQBmZgBmMwBm
AAAz/wAzzAAzmQAzZgAzMwAzAAAA/wAAzAAAmQAAZgAAM+4AAN0A
ALsAAKoAAIgAAHcAAFUAAEQAACIAABEAAADuAADdAAC7AACqAACI
AAB3AABVAABEAAAiAAARAAAA7gAA3QAAuwAAqgAAiAAAdwAAVQAA
RAAAIgAAEe7u7t3d3bu7u6qqqoiIiHd3d1VVVURERCIiIhEREQAA
ACH5BAEAAAAALAAAAAAWABYAAAhIAAEIHEiwoEGBrhIeXEgwoUKG
Cx0+hGhQoiuKBy1irChxY0GNHgeCDAlgZEiTHlFuVImRJUWXEGEy
lBmxI8mSNknm1Dnx5sCAADs=
""" )
}
if __name__ == '__main__':
setLogLevel( 'info' )
app = MiniEdit()
app.mainloop()
+49
View File
@@ -0,0 +1,49 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2020, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
if __name__ == '__main__':
setLogLevel('info')
Minindn.cleanUp()
Minindn.verifyDependencies()
ndn = Minindn()
ndn.start()
info('Starting NFD on nodes\n')
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
info('Starting NLSR on nodes\n')
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr)
MiniNDNCLI(ndn.net)
ndn.stop()
-83
View File
@@ -1,83 +0,0 @@
#!/usr/bin/python
"""
multiping.py: monitor multiple sets of hosts using ping
This demonstrates how one may send a simple shell script to
multiple hosts and monitor their output interactively for a period=
of time.
"""
from mininet.net import Mininet
from mininet.node import Node
from mininet.topo import SingleSwitchTopo
from mininet.log import setLogLevel
from select import poll, POLLIN
from time import time
def chunks( l, n ):
"Divide list l into chunks of size n - thanks Stackoverflow"
return [ l[ i: i + n ] for i in range( 0, len( l ), n ) ]
def startpings( host, targetips ):
"Tell host to repeatedly ping targets"
targetips = ' '.join( targetips )
# Simple ping loop
cmd = ( 'while true; do '
' for ip in %s; do ' % targetips +
' echo -n %s "->" $ip ' % host.IP() +
' `ping -c1 -w 1 $ip | grep packets` ;'
' sleep 1;'
' done; '
'done &' )
print ( '*** Host %s (%s) will be pinging ips: %s' %
( host.name, host.IP(), targetips ) )
host.cmd( cmd )
def multiping( netsize, chunksize, seconds):
"Ping subsets of size chunksize in net of size netsize"
# Create network and identify subnets
topo = SingleSwitchTopo( netsize )
net = Mininet( topo=topo )
net.start()
hosts = net.hosts
subnets = chunks( hosts, chunksize )
# Create polling object
fds = [ host.stdout.fileno() for host in hosts ]
poller = poll()
for fd in fds:
poller.register( fd, POLLIN )
# Start pings
for subnet in subnets:
ips = [ host.IP() for host in subnet ]
#adding bogus to generate packet loss
ips.append( '10.0.0.200' )
for host in subnet:
startpings( host, ips )
# Monitor output
endTime = time() + seconds
while time() < endTime:
readable = poller.poll(1000)
for fd, _mask in readable:
node = Node.outToNode[ fd ]
print '%s:' % node.name, node.monitor().strip()
# Stop pings
for host in hosts:
host.cmd( 'kill %while' )
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' )
multiping( netsize=20, chunksize=4, seconds=10 )
-81
View File
@@ -1,81 +0,0 @@
#!/usr/bin/python
"""
Simple example of sending output to multiple files and
monitoring them
"""
from mininet.topo import SingleSwitchTopo
from mininet.net import Mininet
from mininet.log import setLogLevel
from time import time
from select import poll, POLLIN
from subprocess import Popen, PIPE
def monitorFiles( outfiles, seconds, timeoutms ):
"Monitor set of files and return [(host, line)...]"
devnull = open( '/dev/null', 'w' )
tails, fdToFile, fdToHost = {}, {}, {}
for h, outfile in outfiles.iteritems():
tail = Popen( [ 'tail', '-f', outfile ],
stdout=PIPE, stderr=devnull )
fd = tail.stdout.fileno()
tails[ h ] = tail
fdToFile[ fd ] = tail.stdout
fdToHost[ fd ] = h
# Prepare to poll output files
readable = poll()
for t in tails.values():
readable.register( t.stdout.fileno(), POLLIN )
# Run until a set number of seconds have elapsed
endTime = time() + seconds
while time() < endTime:
fdlist = readable.poll(timeoutms)
if fdlist:
for fd, _flags in fdlist:
f = fdToFile[ fd ]
host = fdToHost[ fd ]
# Wait for a line of output
line = f.readline().strip()
yield host, line
else:
# If we timed out, return nothing
yield None, ''
for t in tails.values():
t.terminate()
devnull.close() # Not really necessary
def monitorTest( N=3, seconds=3 ):
"Run pings and monitor multiple hosts"
topo = SingleSwitchTopo( N )
net = Mininet( topo )
net.start()
hosts = net.hosts
print "Starting test..."
server = hosts[ 0 ]
outfiles, errfiles = {}, {}
for h in hosts:
# Create and/or erase output files
outfiles[ h ] = '/tmp/%s.out' % h.name
errfiles[ h ] = '/tmp/%s.err' % h.name
h.cmd( 'echo >', outfiles[ h ] )
h.cmd( 'echo >', errfiles[ h ] )
# Start pings
h.cmdPrint('ping', server.IP(),
'>', outfiles[ h ],
'2>', errfiles[ h ],
'&' )
print "Monitoring output for", seconds, "seconds"
for h, line in monitorFiles( outfiles, seconds, timeoutms=500 ):
if h:
print '%s: %s' % ( h.name, line )
for h in hosts:
h.cmd('kill %ping')
net.stop()
if __name__ == '__main__':
setLogLevel('info')
monitorTest()
-35
View File
@@ -1,35 +0,0 @@
#!/usr/bin/python
"""
This example shows how to create a network and run multiple tests.
For a more complicated test example, see udpbwtest.py.
"""
from mininet.cli import CLI
from mininet.log import lg, info
from mininet.net import Mininet
from mininet.node import OVSKernelSwitch
from mininet.topolib import TreeTopo
def ifconfigTest( net ):
"Run ifconfig on all hosts in net."
hosts = net.hosts
for host in hosts:
info( host.cmd( 'ifconfig' ) )
if __name__ == '__main__':
lg.setLogLevel( 'info' )
info( "*** Initializing Mininet and kernel modules\n" )
OVSKernelSwitch.setup()
info( "*** Creating network\n" )
network = Mininet( TreeTopo( depth=2, fanout=2 ), switch=OVSKernelSwitch )
info( "*** Starting network\n" )
network.start()
info( "*** Running ping test\n" )
network.pingAll()
info( "*** Running ifconfig test\n" )
ifconfigTest( network )
info( "*** Starting CLI (type 'exit' to exit)\n" )
CLI( network )
info( "*** Stopping network\n" )
network.stop()
-112
View File
@@ -1,112 +0,0 @@
#!/usr/bin/python
"""
Example to create a Mininet topology and connect it to the internet via NAT
through eth0 on the host.
Glen Gibb, February 2011
(slight modifications by BL, 5/13)
"""
from mininet.cli import CLI
from mininet.log import lg
from mininet.node import Node
from mininet.topolib import TreeNet
#################################
def startNAT( root, inetIntf='eth0', subnet='10.0/8' ):
"""Start NAT/forwarding between Mininet and external network
root: node to access iptables from
inetIntf: interface for internet access
subnet: Mininet subnet (default 10.0/8)="""
# Identify the interface connecting to the mininet network
localIntf = root.defaultIntf()
# Flush any currently active rules
root.cmd( 'iptables -F' )
root.cmd( 'iptables -t nat -F' )
# Create default entries for unmatched traffic
root.cmd( 'iptables -P INPUT ACCEPT' )
root.cmd( 'iptables -P OUTPUT ACCEPT' )
root.cmd( 'iptables -P FORWARD DROP' )
# Configure NAT
root.cmd( 'iptables -I FORWARD -i', localIntf, '-d', subnet, '-j DROP' )
root.cmd( 'iptables -A FORWARD -i', localIntf, '-s', subnet, '-j ACCEPT' )
root.cmd( 'iptables -A FORWARD -i', inetIntf, '-d', subnet, '-j ACCEPT' )
root.cmd( 'iptables -t nat -A POSTROUTING -o ', inetIntf, '-j MASQUERADE' )
# Instruct the kernel to perform forwarding
root.cmd( 'sysctl net.ipv4.ip_forward=1' )
def stopNAT( root ):
"""Stop NAT/forwarding between Mininet and external network"""
# Flush any currently active rules
root.cmd( 'iptables -F' )
root.cmd( 'iptables -t nat -F' )
# Instruct the kernel to stop forwarding
root.cmd( 'sysctl net.ipv4.ip_forward=0' )
def fixNetworkManager( root, intf ):
"""Prevent network-manager from messing with our interface,
by specifying manual configuration in /etc/network/interfaces
root: a node in the root namespace (for running commands)
intf: interface name"""
cfile = '/etc/network/interfaces'
line = '\niface %s inet manual\n' % intf
config = open( cfile ).read()
if ( line ) not in config:
print '*** Adding', line.strip(), 'to', cfile
with open( cfile, 'a' ) as f:
f.write( line )
# Probably need to restart network-manager to be safe -
# hopefully this won't disconnect you
root.cmd( 'service network-manager restart' )
def connectToInternet( network, switch='s1', rootip='10.254', subnet='10.0/8'):
"""Connect the network to the internet
switch: switch to connect to root namespace
rootip: address for interface in root namespace
subnet: Mininet subnet"""
switch = network.get( switch )
prefixLen = subnet.split( '/' )[ 1 ]
# Create a node in root namespace
root = Node( 'root', inNamespace=False )
# Prevent network-manager from interfering with our interface
fixNetworkManager( root, 'root-eth0' )
# Create link between root NS and switch
link = network.addLink( root, switch )
link.intf1.setIP( rootip, prefixLen )
# Start network that now includes link to root namespace
network.start()
# Start NAT and establish forwarding
startNAT( root )
# Establish routes from end hosts
for host in network.hosts:
host.cmd( 'ip route flush root 0/0' )
host.cmd( 'route add -net', subnet, 'dev', host.defaultIntf() )
host.cmd( 'route add default gw', rootip )
return root
if __name__ == '__main__':
lg.setLogLevel( 'info')
net = TreeNet( depth=1, fanout=4 )
# Configure and start NATted connectivity
rootnode = connectToInternet( net )
print "*** Hosts are running and should have internet connectivity"
print "*** Type 'exit' or control-D to shut down network"
CLI( net )
# Shut down NAT
stopNAT( rootnode )
net.stop()
+79
View File
@@ -0,0 +1,79 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
import sys
from mininet.log import setLogLevel, info
from mininet.topo import Topo
from minindn.minindn import Minindn
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from nlsr_common import getParser
if __name__ == '__main__':
setLogLevel('info')
topo = Topo()
h1 = topo.addHost('h1')
h2 = topo.addHost('h2')
topo.addLink(h1, h2, delay='10ms')
ndn = Minindn(parser=getParser(), topo=topo)
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
nlsrs = AppManager(ndn, [], Nlsr)
host1 = ndn.net.hosts[0]
nlsrs.startOnNode(host1, security=args.security, faceType=args.faceType,
nFaces=args.faces, routingType=args.routingType)
expectedTotalCount = 500
for i in range(0, expectedTotalCount):
host1.cmd('nlsrc advertise /long/name/to/exceed/max/packet/size/host1/{}'.format(i))
time.sleep(60)
host2 = ndn.net.hosts[1]
nlsrs.startOnNode(host2, security=args.security, faceType=args.faceType,
nFaces=args.faces, routingType=args.routingType)
time.sleep(60)
advertiseCount = int(host2.cmd('nfdc fib | grep host1 | wc -l'))
info(advertiseCount)
if advertiseCount == expectedTotalCount:
info('\nSuccessfully advertised {} prefixes\n'.format(expectedTotalCount))
else:
info('\nAdvertising {} prefixes failed. Exiting...\n'.format(expectedTotalCount))
ndn.stop()
sys.exit(1)
ndn.stop()
+64
View File
@@ -0,0 +1,64 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from minindn.helpers.experiment import Experiment
from nlsr_common import getParser
if __name__ == '__main__':
setLogLevel('info')
ndn = Minindn(parser=getParser())
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
nlsrs = AppManager(ndn, [], Nlsr)
i = 1
info('Starting NLSR on nodes\n')
for host in ndn.net.hosts:
nlsrs.startOnNode(host, security=args.security, sync=args.sync, faceType=args.faceType,
nFaces=args.faces, routingType=args.routingType)
# Wait 1/2 minute between starting NLSRs
# Wait 1 hour before starting last NLSR
if i == len(ndn.net.hosts) - 1:
info('Sleeping 1 hour before starting last NLSR\n')
time.sleep(3600)
else:
time.sleep(30)
i += 1
Experiment.checkConvergence(ndn, ndn.net.hosts, args.ctime, quit=True)
ndn.stop()
+90
View File
@@ -0,0 +1,90 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2021, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from minindn.helpers.experiment import Experiment
from minindn.helpers.nfdc import Nfdc
from minindn.helpers.ndnping import NDNPing
from nlsr_common import getParser
def mcnFailure(ndn, nfds, nlsrs, args):
Experiment.checkConvergence(ndn, ndn.net.hosts, args.ctime, quit=True)
if args.nPings != 0:
Experiment.setupPing(ndn.net.hosts, Nfdc.STRATEGY_BEST_ROUTE)
pingedDict = Experiment.startPctPings(ndn.net, args.nPings, args.pctTraffic)
PING_COLLECTION_TIME_BEFORE_FAILURE = 60
PING_COLLECTION_TIME_AFTER_RECOVERY = 120
time.sleep(PING_COLLECTION_TIME_BEFORE_FAILURE)
mcn = max(ndn.net.hosts, key=lambda host: len(host.intfNames()))
info('Bringing down node {}\n'.format(mcn.name))
nlsrs[mcn.name].stop()
nfds[mcn.name].stop()
time.sleep(args.ctime)
info('Bringing up node {}\n'.format(mcn.name))
nfds[mcn.name].start()
nlsrs[mcn.name].start()
# Restart pings
if args.nPings != 0:
Experiment.setupPing([mcn], Nfdc.STRATEGY_BEST_ROUTE)
for nodeToPing in pingedDict[mcn]:
NDNPing.ping(mcn, nodeToPing, nPings=PING_COLLECTION_TIME_AFTER_RECOVERY)
time.sleep(PING_COLLECTION_TIME_AFTER_RECOVERY)
Experiment.checkConvergence(ndn, ndn.net.hosts, args.ctime, quit=True)
if __name__ == '__main__':
setLogLevel('info')
ndn = Minindn(parser=getParser())
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr, sync=args.sync,
security=args.security, faceType=args.faceType,
nFaces=args.faces, routingType=args.routingType)
mcnFailure(ndn, nfds, nlsrs, args)
if args.isCliEnabled:
MiniNDNCLI(ndn.net)
ndn.stop()
+109
View File
@@ -0,0 +1,109 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2021, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from minindn.helpers.experiment import Experiment
from minindn.helpers.nfdc import Nfdc
from minindn.helpers.ndnping import NDNPing
from nlsr_common import getParser
def multipleFailure(ndn, nfds, nlsrs, args):
Experiment.checkConvergence(ndn, ndn.net.hosts, args.ctime, quit=True)
Experiment.setupPing(ndn.net.hosts, Nfdc.STRATEGY_BEST_ROUTE)
PING_COLLECTION_TIME_BEFORE_FAILURE = 60
FAILURE_INTERVAL = 60
RECOVERY_INTERVAL = 60
# Number of pings required to make it through the full experiment
nInitialPings = (PING_COLLECTION_TIME_BEFORE_FAILURE +
len(ndn.net.hosts) * (FAILURE_INTERVAL + RECOVERY_INTERVAL))
print('Scheduling with {} initial pings'.format(nInitialPings))
pingedDict = Experiment.startPctPings(ndn.net, nInitialPings, args.pctTraffic)
time.sleep(PING_COLLECTION_TIME_BEFORE_FAILURE)
nNodesRemainingToFail = len(ndn.net.hosts)
for host in ndn.net.hosts:
# Fail the node
info('Bringing down node {}\n'.format(host.name))
nlsrs[host.name].stop()
nfds[host.name].stop()
# Stay in failure state for FAILURE_INTERVAL seconds
time.sleep(FAILURE_INTERVAL)
# Bring the node back up
start_time = time.time()
info('Bringing up node {}\n'.format(host.name))
nfds[host.name].start()
nlsrs[host.name].start()
Experiment.setupPing([host], Nfdc.STRATEGY_BEST_ROUTE)
recovery_time = int(time.time() - start_time)
# Number of pings required to reach the end of the test
nNodesRemainingToFail -= 1
nPings = ((RECOVERY_INTERVAL - recovery_time) +
nNodesRemainingToFail * (FAILURE_INTERVAL + RECOVERY_INTERVAL))
info('Scheduling with {} remaining pings\n'.format(nPings))
# Restart pings
for nodeToPing in pingedDict[host]:
NDNPing.ping(host, nodeToPing, nPings=nPings)
time.sleep(RECOVERY_INTERVAL - recovery_time)
Experiment.checkConvergence(ndn, ndn.net.hosts, args.ctime, quit=True)
if __name__ == '__main__':
setLogLevel('info')
ndn = Minindn(parser=getParser())
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr, sync=args.sync,
security=args.security, faceType=args.faceType,
nFaces=args.faces, routingType=args.routingType)
multipleFailure(ndn, nfds, nlsrs, args)
if args.isCliEnabled:
MiniNDNCLI(ndn.net)
ndn.stop()
+57
View File
@@ -0,0 +1,57 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import argparse
def getParser():
parser = argparse.ArgumentParser()
parser.add_argument('--ctime', type=int, default=60,
help='Specify convergence time for the topology (Default: 60 seconds)')
parser.add_argument('--faces', type=int, default=3,
help='Specify number of max faces per prefix for NLSR 0-60')
parser.add_argument('--routing', dest='routingType', default='link-state',
choices=['link-state', 'hr', 'dry'],
help='''Choose routing type, dry = link-state is used
but hr is calculated for comparision.''')
parser.add_argument('--sync', dest='sync', default='psync',
choices=['chronosync', 'psync'],
help='choose the sync protocol to be used by NLSR.')
parser.add_argument('--security', action='store_true', dest='security',
help='Enables NLSR security')
parser.add_argument('--face-type', dest='faceType', default='udp', choices=['udp', 'tcp'])
parser.add_argument('--no-cli', action='store_false', dest='isCliEnabled',
help='Run experiments and exit without showing the command line interface')
parser.add_argument('--pct-traffic', dest='pctTraffic', type=float, default=1.0,
help='Specify the percentage of nodes each node should ping')
parser.add_argument('--nPings', type=int, default=300,
help='Number of pings to perform between each node in the experiment')
return parser
+63
View File
@@ -0,0 +1,63 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
from mininet.log import setLogLevel
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from minindn.helpers.experiment import Experiment
from minindn.helpers.nfdc import Nfdc
from nlsr_common import getParser
if __name__ == '__main__':
setLogLevel('info')
ndn = Minindn(parser=getParser())
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr, sync=args.sync,
security=args.security, faceType=args.faceType,
nFaces=args.faces, routingType=args.routingType,
logLevel='ndn.*=TRACE:nlsr.*=TRACE')
Experiment.checkConvergence(ndn, ndn.net.hosts, args.ctime, quit=False)
if args.nPings != 0:
Experiment.setupPing(ndn.net.hosts, Nfdc.STRATEGY_BEST_ROUTE)
Experiment.startPctPings(ndn.net, args.nPings, args.pctTraffic)
time.sleep(args.nPings + 10)
if args.isCliEnabled:
MiniNDNCLI(ndn.net)
ndn.stop()
+85
View File
@@ -0,0 +1,85 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2021, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
import sys
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from minindn.helpers.experiment import Experiment
from nlsr_common import getParser
if __name__ == '__main__':
setLogLevel('info')
ndn = Minindn(parser=getParser())
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr, sync=args.sync,
security=args.security, faceType=args.faceType,
nFaces=args.faces, routingType=args.routingType)
Experiment.checkConvergence(ndn, ndn.net.hosts, args.ctime, quit=True)
firstNode = ndn.net.hosts[0]
if args.security:
firstNode.cmd('ndnsec-set-default /ndn/{}-site/%C1.Operator/op'.format(firstNode.name))
info('Testing advertise\n')
firstNode.cmd('nlsrc advertise /testPrefix')
time.sleep(30)
for host in ndn.net.hosts:
if host.name != firstNode.name:
if (int(host.cmd('nfdc fib | grep testPrefix | wc -l')) != 1 or
int(host.cmd('nlsrc status | grep testPrefix | wc -l')) != 1):
info('Advertise test failed\n')
ndn.stop()
sys.exit(1)
info('Testing withdraw\n')
firstNode.cmd('nlsrc withdraw /testPrefix')
time.sleep(30)
for host in ndn.net.hosts:
if host.name != firstNode.name:
if (int(host.cmd('nfdc fib | grep testPrefix | wc -l')) != 0 or
int(host.cmd('nlsrc status | grep testPrefix | wc -l')) != 0):
info('Withdraw test failed\n')
ndn.stop()
sys.exit(1)
if args.isCliEnabled:
MiniNDNCLI(ndn.net)
ndn.stop()
+53
View File
@@ -0,0 +1,53 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2020, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.apps.app_manager import AppManager
from minindn.util import MiniNDNCLI
from minindn.apps.nfd import Nfd
from minindn.apps.nlsr import Nlsr
from minindn.apps.tshark import Tshark
if __name__ == '__main__':
setLogLevel('info')
Minindn.cleanUp()
Minindn.verifyDependencies()
ndn = Minindn()
ndn.start()
info('Starting tshark logging on nodes\n')
tshark = AppManager(ndn, ndn.net.hosts, Tshark, logFolder="./log/", singleLogFile=False)
info('Starting NFD on nodes\n')
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
info('Starting NLSR on nodes\n')
nlsrs = AppManager(ndn, ndn.net.hosts, Nlsr)
MiniNDNCLI(ndn.net)
ndn.stop()
+121
View File
@@ -0,0 +1,121 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2021, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from subprocess import PIPE
from mininet.log import setLogLevel, info
from mininet.topo import Topo
from minindn.minindn import Minindn
from minindn.apps.app_manager import AppManager
from minindn.util import MiniNDNCLI, getPopen
from minindn.apps.nfd import Nfd
from minindn.helpers.nfdc import Nfdc
PREFIX = "/example"
def printOutput(output):
_out = output.decode("utf-8").split("\n")
for _line in _out:
info(_line + "\n")
def run():
Minindn.cleanUp()
Minindn.verifyDependencies()
# Topology can be created/modified using Mininet topo object
topo = Topo()
info("Setup\n")
# add hosts
a = topo.addHost('a')
b = topo.addHost('b')
c = topo.addHost('c')
# add links
topo.addLink(a, b, delay='10ms', bw=2.5) # bw = bandwidth
topo.addLink(b, c, delay='10ms', bw=2.5)
info(topo.links(withInfo=True))
ndn = Minindn(topo=topo)
ndn.start()
# configure and start nfd on each node
info("Configuring NFD111\n")
AppManager(ndn, ndn.net.hosts, Nfd, logLevel="DEBUG")
"""
There are multiple ways of setting up routes in Mini-NDN
refer: https://minindn.memphis.edu/experiment.html#routing-options
It can also be set manually as follows. The important bit to note here
is the use of the Nfdc command
"""
for link in topo.links(withInfo=True):
node1, node2, node_info = link
host1 = ndn.net[node1]
host2 = ndn.net[node2]
interface = host2.connectionsTo(host1)[0][0]
interface_ip = interface.IP()
bandwidth = interface.params.get("bw", 100) * 1000000
info(f"Setting up route from {node1} to {node2} with bandwidth {bandwidth}\n")
Nfdc.createFace(host1, interface_ip, bandwidth=bandwidth)
Nfdc.registerRoute(host1, PREFIX, interface_ip, cost=0)
# links = {"a":["b"], "b":["c"]}
# for first in links:
# for second in links[first]:
# host1 = ndn.net[first]
# host2 = ndn.net[second]
# interface = host2.connectionsTo(host1)[0][0]
# interface_ip = interface.IP()
# Nfdc.createFace(host1, interface_ip)
# Nfdc.registerRoute(host1, PREFIX, interface_ip, cost=0)
# Start ping server
info("Starting pings...\n")
pingserver_log = open("{}/c/ndnpingserver.log".format(ndn.workDir), "w")
getPopen(ndn.net["c"], "ndnpingserver {}".format(PREFIX), stdout=pingserver_log,\
stderr=pingserver_log)
# start ping client
ping1 = getPopen(ndn.net["a"], "ndnping {} -c 5".format(PREFIX), stdout=PIPE, stderr=PIPE)
ping1.wait()
printOutput(ping1.stdout.read())
interface = ndn.net["b"].connectionsTo(ndn.net["a"])[0][0]
info("Failing link\n") # failing link by setting link loss to 100%
interface.config(delay="10ms", bw=10, loss=100)
info ("\n starting ping2 client \n")
ping2 = getPopen(ndn.net["a"], "ndnping {} -c 5".format(PREFIX), stdout=PIPE, stderr=PIPE)
ping2.wait()
printOutput(ping2.stdout.read())
interface.config(delay="10ms", bw=10, loss=0) # bringing back the link
info("\nExperiment Completed!\n")
MiniNDNCLI(ndn.net)
ndn.stop()
if __name__ == '__main__':
setLogLevel("info")
run()
-36
View File
@@ -1,36 +0,0 @@
#!/usr/bin/python
"""
This example monitors a number of hosts using host.popen() and
pmonitor()
"""
from mininet.net import Mininet
from mininet.node import CPULimitedHost
from mininet.topo import SingleSwitchTopo
from mininet.log import setLogLevel
from mininet.util import custom, pmonitor
def monitorhosts( hosts=5, sched='cfs' ):
"Start a bunch of pings and monitor them using popen"
mytopo = SingleSwitchTopo( hosts )
cpu = .5 / hosts
myhost = custom( CPULimitedHost, cpu=cpu, sched=sched )
net = Mininet( topo=mytopo, host=myhost )
net.start()
# Start a bunch of pings
popens = {}
last = net.hosts[ -1 ]
for host in net.hosts:
popens[ host ] = host.popen( "ping -c5 %s" % last.IP() )
last = host
# Monitor them and print output
for host, line in pmonitor( popens ):
if host:
print "<%s>: %s" % ( host.name, line.strip() )
# Done
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' )
monitorhosts( hosts=5 )
-33
View File
@@ -1,33 +0,0 @@
#!/usr/bin/python
"Monitor multiple hosts using popen()/pmonitor()"
from mininet.net import Mininet
from mininet.topo import SingleSwitchTopo
from mininet.util import pmonitor
from time import time
from signal import SIGINT
def pmonitorTest( N=3, seconds=10 ):
"Run pings and monitor multiple hosts using pmonitor"
topo = SingleSwitchTopo( N )
net = Mininet( topo )
net.start()
hosts = net.hosts
print "Starting test..."
server = hosts[ 0 ]
popens = {}
for h in hosts:
popens[ h ] = h.popen('ping', server.IP() )
print "Monitoring output for", seconds, "seconds"
endTime = time() + seconds
for h, line in pmonitor( popens, timeoutms=500 ):
if h:
print '<%s>: %s' % ( h.name, line ),
if time() >= endTime:
for p in popens.values():
p.send_signal( SIGINT )
net.stop()
if __name__ == '__main__':
pmonitorTest()
+81
View File
@@ -0,0 +1,81 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
import sys
from mininet.log import setLogLevel, info
from minindn.minindn import Minindn
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.helpers.nfdc import Nfdc
def registerRouteToAllNeighbors(ndn, host, syncPrefix):
for node in ndn.net.hosts:
for neighbor in node.connectionsTo(host):
ip = node.IP(neighbor[0])
faceID = Nfdc.createFace(host, ip)
Nfdc.registerRoute(host, syncPrefix, faceID)
if __name__ == '__main__':
setLogLevel('info')
ndn = Minindn()
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
syncPrefix = "/sync"
numUserPrefixesPerNode = 2
maxUpdatesPerUserPrefixPerNode = 3
for host in ndn.net.hosts:
Nfdc.setStrategy(host, syncPrefix, Nfdc.STRATEGY_MULTICAST)
registerRouteToAllNeighbors(ndn, host, syncPrefix)
info('Starting psync-full-sync on all the nodes\n')
for host in ndn.net.hosts:
host.cmd('export NDN_LOG=examples.FullSyncApp=INFO')
host.cmd('psync-full-sync {} {} {} {} &> psync.logs &'
.format(syncPrefix, host.name, numUserPrefixesPerNode,
maxUpdatesPerUserPrefixPerNode))
info('Sleeping 5 minutes for convergence\n')
# Estimated time for 4 node default topology
time.sleep(300)
totalUpdates = int(host.cmd('grep -r Update {}/*/psync.logs | wc -l'
.format(ndn.workDir)))
expectedUpdates = (maxUpdatesPerUserPrefixPerNode *
len(ndn.net.hosts) * (len(ndn.net.hosts) - 1) * numUserPrefixesPerNode)
if totalUpdates == expectedUpdates:
info('PSync full sync has successfully converged.\n')
else:
info('PSync full sync convergence was not successful. Exiting...\n')
ndn.stop()
sys.exit(1)
+67
View File
@@ -0,0 +1,67 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2019, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import time
import sys
from mininet.log import setLogLevel, info
from mininet.topo import Topo
from minindn.minindn import Minindn
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
if __name__ == '__main__':
setLogLevel('info')
topo = Topo()
topo.addHost('h1')
ndn = Minindn(topo=topo)
args = ndn.args
ndn.start()
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
host1 = ndn.net.hosts[0]
host1.cmd('export NDN_LOG=examples.PartialSyncProducerApp=INFO')
host1.cmd('psync-producer /sync /{} 10 1 &> producer.log &'.format(host1.name))
time.sleep(1)
host1.cmd('export NDN_LOG=examples.PartialSyncConsumerApp=INFO:$NDN_LOG')
host1.cmd('psync-consumer /sync 5 &> consumer.log &')
info('Sleeping 90 seconds for convergence\n')
time.sleep(90)
consumerSubs = int(host1.cmd('cat consumer.log | grep -c Subscribing'))
consumerUpdates = int(host1.cmd('cat consumer.log | grep -c Update'))
producerPublish = int(host1.cmd('cat producer.log | grep -c Publish'))
if consumerSubs == 5 and consumerUpdates == 5 and producerPublish == 10:
info('PSync partial sync has successfully converged.\n')
else:
info('PSync partial sync convergence was not successful. Exiting...\n')
ndn.stop()
sys.exit(1)
+111
View File
@@ -0,0 +1,111 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2021, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
from subprocess import PIPE
from mininet.log import setLogLevel, info
from mininet.topo import Topo
from minindn.minindn import Minindn
from minindn.apps.app_manager import AppManager
from minindn.util import MiniNDNCLI, getPopen
from minindn.apps.nfd import Nfd
from minindn.helpers.nfdc import Nfdc
PREFIX = "/A"
def printOutput(output):
_out = output.decode("utf-8").split("\n")
for _line in _out:
info(_line + "\n")
def run():
Minindn.cleanUp()
Minindn.verifyDependencies()
# Topology can be created/modified using Mininet topo object
topo = Topo()
info("Setup\n")
# add hosts
a = topo.addHost('a')
b = topo.addHost('b')
# add links
topo.addLink(a, b, delay='10ms', bw=10) # bw = bandwidth
info(topo.links(withInfo=True))
ndn = Minindn(topo=topo)
ndn.start()
# configure and start nfd on each node
info("Configuring NFD\n")
AppManager(ndn, ndn.net.hosts, Nfd, logLevel="INFO")
"""
There are multiple ways of setting up routes in Mini-NDN
refer: https://minindn.memphis.edu/experiment.html#routing-options
It can also be set manually as follows. The important bit to note here
is the use of the Nfdc command
"""
for link in topo.links(withInfo=True):
node1, node2, node_info = link
host1 = ndn.net[node1]
host2 = ndn.net[node2]
interface = host2.connectionsTo(host1)[0][0]
interface_ip = interface.IP()
bandwidth = interface.params.get("bw", 100) * 1000000
info(f"Setting up route from {node1} to {node2} with bandwidth {bandwidth}\n")
Nfdc.createFace(host1, interface_ip, bandwidth=bandwidth)
Nfdc.registerRoute(host1, PREFIX, interface_ip, cost=0)
# Start cc server
info("Starting cc...\n")
qsccp_server_log = open(f"{ndn.workDir}/qsccp-demo/qsccp-server.log", "w")
getPopen(ndn.net["b"], "cc-producer --prefix {}".format(PREFIX), stdout=qsccp_server_log,\
stderr=qsccp_server_log)
# start cc client
qsccp_client_log = open(f"{ndn.workDir}/qsccp-demo/qsccp-client.log", "w")
ping1 = getPopen(ndn.net["a"], "qsccp-client --prefix {} --timingStop 10000".format(PREFIX), stdout=qsccp_client_log, stderr=qsccp_client_log)
ping1.wait()
# printOutput(ping1.stdout.read())
# interface = ndn.net["b"].connectionsTo(ndn.net["a"])[0][0]
# info("Failing link\n") # failing link by setting link loss to 100%
# interface.config(delay="10ms", bw=10, loss=100)
# info ("\n starting ping2 client \n")
# ping2 = getPopen(ndn.net["a"], "ndnping {} -c 5".format(PREFIX), stdout=PIPE, stderr=PIPE)
# ping2.wait()
# printOutput(ping2.stdout.read())
# interface.config(delay="10ms", bw=10, loss=0) # bringing back the link
info("\nExperiment Completed!\n")
MiniNDNCLI(ndn.net)
ndn.stop()
if __name__ == '__main__':
setLogLevel("info")
run()
-68
View File
@@ -1,68 +0,0 @@
#!/usr/bin/python
"""
Build a simple network from scratch, using mininet primitives.
This is more complicated than using the higher-level classes,
but it exposes the configuration details and allows customization.
For most tasks, the higher-level API will be preferable.
"""
from mininet.net import Mininet
from mininet.node import Node
from mininet.link import Link
from mininet.log import setLogLevel, info
from mininet.util import quietRun
from time import sleep
def scratchNet( cname='controller', cargs='-v ptcp:' ):
"Create network from scratch using Open vSwitch."
info( "*** Creating nodes\n" )
controller = Node( 'c0', inNamespace=False )
switch = Node( 's0', inNamespace=False )
h0 = Node( 'h0' )
h1 = Node( 'h1' )
info( "*** Creating links\n" )
Link( h0, switch )
Link( h1, switch )
info( "*** Configuring hosts\n" )
h0.setIP( '192.168.123.1/24' )
h1.setIP( '192.168.123.2/24' )
info( str( h0 ) + '\n' )
info( str( h1 ) + '\n' )
info( "*** Starting network using Open vSwitch\n" )
controller.cmd( cname + ' ' + cargs + '&' )
switch.cmd( 'ovs-vsctl del-br dp0' )
switch.cmd( 'ovs-vsctl add-br dp0' )
for intf in switch.intfs.values():
print switch.cmd( 'ovs-vsctl add-port dp0 %s' % intf )
# Note: controller and switch are in root namespace, and we
# can connect via loopback interface
switch.cmd( 'ovs-vsctl set-controller dp0 tcp:127.0.0.1:6633' )
info( '*** Waiting for switch to connect to controller' )
while 'is_connected' not in quietRun( 'ovs-vsctl show' ):
sleep( 1 )
info( '.' )
info( '\n' )
info( "*** Running test\n" )
h0.cmdPrint( 'ping -c1 ' + h1.IP() )
info( "*** Stopping network\n" )
controller.cmd( 'kill %' + cname )
switch.cmd( 'ovs-vsctl del-br dp0' )
switch.deleteIntfs()
info( '\n' )
if __name__ == '__main__':
setLogLevel( 'info' )
info( '*** Scratch network demo (kernel datapath)\n' )
Mininet.init()
scratchNet()
-73
View File
@@ -1,73 +0,0 @@
#!/usr/bin/python
"""
Build a simple network from scratch, using mininet primitives.
This is more complicated than using the higher-level classes,
but it exposes the configuration details and allows customization.
For most tasks, the higher-level API will be preferable.
This version uses the user datapath and an explicit control network.
"""
from mininet.net import Mininet
from mininet.node import Node
from mininet.link import Link
from mininet.log import setLogLevel, info
def linkIntfs( node1, node2 ):
"Create link from node1 to node2 and return intfs"
link = Link( node1, node2 )
return link.intf1, link.intf2
def scratchNetUser( cname='controller', cargs='ptcp:' ):
"Create network from scratch using user switch."
# It's not strictly necessary for the controller and switches
# to be in separate namespaces. For performance, they probably
# should be in the root namespace. However, it's interesting to
# see how they could work even if they are in separate namespaces.
info( '*** Creating Network\n' )
controller = Node( 'c0' )
switch = Node( 's0')
h0 = Node( 'h0' )
h1 = Node( 'h1' )
cintf, sintf = linkIntfs( controller, switch )
h0intf, sintf1 = linkIntfs( h0, switch )
h1intf, sintf2 = linkIntfs( h1, switch )
info( '*** Configuring control network\n' )
controller.setIP( '10.0.123.1/24', intf=cintf )
switch.setIP( '10.0.123.2/24', intf=sintf)
info( '*** Configuring hosts\n' )
h0.setIP( '192.168.123.1/24', intf=h0intf )
h1.setIP( '192.168.123.2/24', intf=h1intf )
info( '*** Network state:\n' )
for node in controller, switch, h0, h1:
info( str( node ) + '\n' )
info( '*** Starting controller and user datapath\n' )
controller.cmd( cname + ' ' + cargs + '&' )
switch.cmd( 'ifconfig lo 127.0.0.1' )
intfs = [ str( i ) for i in sintf1, sintf2 ]
switch.cmd( 'ofdatapath -i ' + ','.join( intfs ) + ' ptcp: &' )
switch.cmd( 'ofprotocol tcp:' + controller.IP() + ' tcp:localhost &' )
info( '*** Running test\n' )
h0.cmdPrint( 'ping -c1 ' + h1.IP() )
info( '*** Stopping network\n' )
controller.cmd( 'kill %' + cname )
switch.cmd( 'kill %ofdatapath' )
switch.cmd( 'kill %ofprotocol' )
switch.deleteIntfs()
info( '\n' )
if __name__ == '__main__':
setLogLevel( 'info' )
info( '*** Scratch network demo (user datapath)\n' )
Mininet.init()
scratchNetUser()
-49
View File
@@ -1,49 +0,0 @@
#!/usr/bin/python
"""
Simple example of setting network and CPU parameters
NOTE: link params limit BW, add latency, and loss.
There is a high chance that pings WILL fail and that
iperf will hang indefinitely if the TCP handshake fails
to complete.
"""
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.node import CPULimitedHost
from mininet.link import TCLink
from mininet.util import dumpNodeConnections
from mininet.log import setLogLevel
class SingleSwitchTopo(Topo):
"Single switch connected to n hosts."
def __init__(self, n=2, **opts):
Topo.__init__(self, **opts)
switch = self.addSwitch('s1')
for h in range(n):
# Each host gets 50%/n of system CPU
host = self.addHost('h%s' % (h + 1),
cpu=.5 / n)
# 10 Mbps, 5ms delay, 10% loss
self.addLink(host, switch,
bw=10, delay='5ms', loss=10, use_htb=True)
def perfTest():
"Create network and run simple performance test"
topo = SingleSwitchTopo(n=4)
net = Mininet(topo=topo,
host=CPULimitedHost, link=TCLink)
net.start()
print "Dumping host connections"
dumpNodeConnections(net.hosts)
print "Testing network connectivity"
net.pingAll()
print "Testing bandwidth between h1 and h4"
h1, h4 = net.getNodeByName('h1', 'h4')
net.iperf((h1, h4))
net.stop()
if __name__ == '__main__':
setLogLevel('info')
perfTest()
-81
View File
@@ -1,81 +0,0 @@
#!/usr/bin/python
"""
Create a network and start sshd(8) on each host.
While something like rshd(8) would be lighter and faster,
(and perfectly adequate on an in-machine network)
the advantage of running sshd is that scripts can work
unchanged on mininet and hardware.
In addition to providing ssh access to hosts, this example
demonstrates:
- creating a convenience function to construct networks
- connecting the host network to the root namespace
- running server processes (sshd in this case) on hosts
"""
import sys
from mininet.net import Mininet
from mininet.cli import CLI
from mininet.log import lg
from mininet.node import Node
from mininet.topolib import TreeTopo
from mininet.link import Link
def TreeNet( depth=1, fanout=2, **kwargs ):
"Convenience function for creating tree networks."
topo = TreeTopo( depth, fanout )
return Mininet( topo, **kwargs )
def connectToRootNS( network, switch, ip, routes ):
"""Connect hosts to root namespace via switch. Starts network.
network: Mininet() network object
switch: switch to connect to root namespace
ip: IP address for root namespace node
routes: host networks to route to"""
# Create a node in root namespace and link to switch 0
root = Node( 'root', inNamespace=False )
intf = Link( root, switch ).intf1
root.setIP( ip, intf=intf )
# Start network that now includes link to root namespace
network.start()
# Add routes from root ns to hosts
for route in routes:
root.cmd( 'route add -net ' + route + ' dev ' + str( intf ) )
def sshd( network, cmd='/usr/sbin/sshd', opts='-D',
ip='10.123.123.1/32', routes=None, switch=None ):
"""Start a network, connect it to root ns, and run sshd on all hosts.
ip: root-eth0 IP address in root namespace (10.123.123.1/32)
routes: Mininet host networks to route to (10.0/24)
switch: Mininet switch to connect to root namespace (s1)"""
if not switch:
switch = network[ 's1' ] # switch to use
if not routes:
routes = [ '10.0.0.0/24' ]
connectToRootNS( network, switch, ip, routes )
for host in network.hosts:
host.cmd( cmd + ' ' + opts + '&' )
print
print "*** Hosts are running sshd at the following addresses:"
print
for host in network.hosts:
print host.name, host.IP()
print
print "*** Type 'exit' or control-D to shut down network"
CLI( network )
for host in network.hosts:
host.cmd( 'kill %' + cmd )
network.stop()
if __name__ == '__main__':
lg.setLogLevel( 'info')
net = TreeNet( depth=1, fanout=4 )
# get sshd args from the command line or use default args
# useDNS=no -u0 to avoid reverse DNS lookup timeout
opts = ' '.join( sys.argv[ 1: ] ) if len( sys.argv ) > 1 else (
'-D -o UseDNS=no -u0' )
sshd( net, opts=opts )
+100
View File
@@ -0,0 +1,100 @@
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2015-2020, The University of Memphis,
# Arizona Board of Regents,
# Regents of the University of California.
#
# This file is part of Mini-NDN.
# See AUTHORS.md for a complete list of Mini-NDN authors and contributors.
#
# Mini-NDN is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mini-NDN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mini-NDN, e.g., in COPYING.md file.
# If not, see <http://www.gnu.org/licenses/>.
import argparse
import sys
from mininet.log import setLogLevel, info
from mininet.topo import Topo
from minindn.minindn import Minindn
from minindn.util import MiniNDNCLI
from minindn.apps.app_manager import AppManager
from minindn.apps.nfd import Nfd
from minindn.helpers.ndn_routing_helper import NdnRoutingHelper
if __name__ == '__main__':
setLogLevel('info')
Minindn.cleanUp()
Minindn.verifyDependencies()
parser = argparse.ArgumentParser()
parser.add_argument('--face-type', dest='faceType', default='udp', choices=['udp', 'tcp'])
parser.add_argument('--routing', dest='routingType', default='link-state',
choices=['link-state', 'hr', 'dry'],
help='''Choose routing type, dry = link-state is used
but hr is calculated for comparision.''')
'''
Experiment run with default topology, test cases won't work with other topologies
# With calculateNPossibleRoutes,
10 # routing = hr, N = All, from A, 3 routes needs to added to NFD.
a +++++++ b # a - b -- cost 10
+ + # a - c -- cost 10
10 + + 10 # a - d -- cost 20
+ + # Same goes for B being a source.
c d #
'''
topo = Topo()
a = topo.addHost('a')
b = topo.addHost('b')
c = topo.addHost('c')
d = topo.addHost('d')
topo.addLink(a, b, delay='10ms')
topo.addLink(a, c, delay='10ms')
topo.addLink(b, d, delay='10ms')
ndn = Minindn(parser=parser, topo=topo)
ndn.start()
info('Starting NFD on nodes\n')
nfds = AppManager(ndn, ndn.net.hosts, Nfd)
info('Adding static routes to NFD\n')
grh = NdnRoutingHelper(ndn.net, ndn.args.faceType, ndn.args.routingType)
# For all host, pass ndn.net.hosts or a list, [ndn.net['a'], ..] or [ndn.net.hosts[0],.]
grh.addOrigin([ndn.net['a']], ["/abc"])
grh.calculateNPossibleRoutes()
'''
prefix "/abc" is advertise from node A, it should be reachable from all other nodes.
'''
routesFromA = ndn.net['a'].cmd("nfdc route | grep -v '/localhost/nfd'")
if '/ndn/b-site/b' not in routesFromA or \
'/ndn/c-site/c' not in routesFromA or \
'/ndn/d-site/d' not in routesFromA:
info("Route addition failed\n")
routesToPrefix = ndn.net['b'].cmd("nfdc fib | grep '/abc'")
if '/abc' not in routesToPrefix:
info("Missing route to advertised prefix, Route addition failed\n")
ndn.net.stop()
sys.exit(1)
info('Route addition to NFD completed\n')
MiniNDNCLI(ndn.net)
ndn.stop()
-29
View File
@@ -1,29 +0,0 @@
#!/usr/bin/env python
"""
Run all mininet.examples tests
-v : verbose output
-quick : skip tests that take more than ~30 seconds
"""
import unittest
import os
import sys
from mininet.util import ensureRoot
from mininet.clean import cleanup
def runTests( testDir, verbosity=1 ):
"discover and run all tests in testDir"
# ensure root and cleanup before starting tests
ensureRoot()
cleanup()
# discover all tests in testDir
testSuite = unittest.defaultTestLoader.discover( testDir )
# run tests
unittest.TextTestRunner( verbosity=verbosity ).run( testSuite )
if __name__ == '__main__':
# get the directory containing example tests
testDir = os.path.dirname( os.path.realpath( __file__ ) )
verbosity = 2 if '-v' in sys.argv else 1
runTests( testDir, verbosity )
-62
View File
@@ -1,62 +0,0 @@
#!/usr/bin/env python
"""
Tests for baresshd.py
"""
import unittest
import pexpect
from time import sleep
from mininet.clean import cleanup, sh
class testBareSSHD( unittest.TestCase ):
opts = [ '\(yes/no\)\?', 'Welcome to h1', 'refused', pexpect.EOF, pexpect.TIMEOUT ]
def connected( self ):
"Log into ssh server, check banner, then exit"
p = pexpect.spawn( 'ssh 10.0.0.1 -i /tmp/ssh/test_rsa exit' )
while True:
index = p.expect( self.opts )
if index == 0:
p.sendline( 'yes' )
elif index == 1:
return True
else:
return False
def setUp( self ):
# verify that sshd is not running
self.assertFalse( self.connected() )
# create public key pair for testing
sh( 'rm -rf /tmp/ssh' )
sh( 'mkdir /tmp/ssh' )
sh( "ssh-keygen -t rsa -P '' -f /tmp/ssh/test_rsa" )
sh( 'cat /tmp/ssh/test_rsa.pub >> /tmp/ssh/authorized_keys' )
# run example with custom sshd args
cmd = ( 'python -m mininet.examples.baresshd '
'-o AuthorizedKeysFile=/tmp/ssh/authorized_keys '
'-o StrictModes=no' )
sh( cmd )
def testSSH( self ):
"Simple test to verify that we can ssh into h1"
result = False
# try to connect up to 3 times; sshd can take a while to start
for _ in range( 3 ):
result = self.connected()
if result:
break
else:
sleep( 1 )
self.assertTrue( result )
def tearDown( self ):
# kill the ssh process
sh( "ps aux | grep 'ssh.*Banner' | awk '{ print $2 }' | xargs kill" )
cleanup()
# remove public key pair
sh( 'rm -rf /tmp/ssh' )
if __name__ == '__main__':
unittest.main()
-66
View File
@@ -1,66 +0,0 @@
#!/usr/bin/env python
"""
Tests for bind.py
"""
import unittest
import pexpect
class testBind( unittest.TestCase ):
prompt = 'mininet>'
def setUp( self ):
self.net = pexpect.spawn( 'python -m mininet.examples.bind' )
self.net.expect( "Private Directories: \[([\w\s,'/]+)\]" )
self.directories = []
# parse directories from mn output
for d in self.net.match.group(1).split(', '):
self.directories.append( d.strip("'") )
self.net.expect( self.prompt )
self.assertTrue( len( self.directories ) > 0 )
def testCreateFile( self ):
"Create a file, a.txt, in the first private directory and verify"
fileName = 'a.txt'
directory = self.directories[ 0 ]
path = directory + '/' + fileName
self.net.sendline( 'h1 touch %s; ls %s' % ( path, directory ) )
index = self.net.expect( [ fileName, self.prompt ] )
self.assertTrue( index == 0 )
self.net.expect( self.prompt )
self.net.sendline( 'h1 rm %s' % path )
self.net.expect( self.prompt )
def testIsolation( self ):
"Create a file in two hosts and verify that contents are different"
fileName = 'b.txt'
directory = self.directories[ 0 ]
path = directory + '/' + fileName
contents = { 'h1' : '1', 'h2' : '2' }
# Verify file doesn't exist, then write private copy of file
for host in contents:
value = contents[ host ]
self.net.sendline( '%s cat %s' % ( host, path ) )
self.net.expect( 'No such file' )
self.net.expect( self.prompt )
self.net.sendline( '%s echo %s > %s' % ( host, value, path ) )
self.net.expect( self.prompt )
# Verify file contents
for host in contents:
value = contents[ host ]
self.net.sendline( '%s cat %s' % ( host, path ) )
self.net.expect( value )
self.net.expect( self.prompt )
self.net.sendline( '%s rm %s' % ( host, path ) )
self.net.expect( self.prompt )
# TODO: need more tests
def tearDown( self ):
self.net.sendline( 'exit' )
self.net.wait()
if __name__ == '__main__':
unittest.main()
-48
View File
@@ -1,48 +0,0 @@
#!/usr/bin/env python
"""
Tests for controllers.py and controllers2.py
"""
import unittest
import pexpect
class testControllers( unittest.TestCase ):
prompt = 'mininet>'
def connectedTest( self, name, cmap ):
"Verify that switches are connected to the controller specified by cmap"
p = pexpect.spawn( 'python -m %s' % name )
p.expect( self.prompt )
# but first a simple ping test
p.sendline( 'pingall' )
p.expect ( '(\d+)% dropped' )
percent = int( p.match.group( 1 ) ) if p.match else -1
self.assertEqual( percent, 0 )
p.expect( self.prompt )
# verify connected controller
for switch in cmap:
p.sendline( 'sh ovs-vsctl get-controller %s' % switch )
p.expect( 'tcp:([\d.:]+)')
actual = p.match.group(1)
expected = cmap[ switch ]
self.assertEqual( actual, expected )
p.expect( self.prompt )
p.sendline( 'exit' )
p.wait()
def testControllers( self ):
c0 = '127.0.0.1:6633'
c1 = '127.0.0.1:6634'
cmap = { 's1': c0, 's2': c1, 's3': c0 }
self.connectedTest( 'mininet.examples.controllers', cmap )
def testControllers2( self ):
c0 = '127.0.0.1:6633'
c1 = '127.0.0.1:6634'
cmap = { 's1': c0, 's2': c1 }
self.connectedTest( 'mininet.examples.controllers2', cmap )
if __name__ == '__main__':
unittest.main()
-47
View File
@@ -1,47 +0,0 @@
#!/usr/bin/env python
"""
Test for controlnet.py
"""
import unittest
import pexpect
class testControlNet( unittest.TestCase ):
prompt = 'mininet>'
def testPingall( self ):
"Simple pingall test that verifies 0% packet drop in data network"
p = pexpect.spawn( 'python -m mininet.examples.controlnet' )
p.expect( self.prompt )
p.sendline( 'pingall' )
p.expect ( '(\d+)% dropped' )
percent = int( p.match.group( 1 ) ) if p.match else -1
self.assertEqual( percent, 0 )
p.expect( self.prompt )
p.sendline( 'exit' )
p.wait()
def testFailover( self ):
"Kill controllers and verify that switch, s1, fails over properly"
count = 1
p = pexpect.spawn( 'python -m mininet.examples.controlnet' )
p.expect( self.prompt )
lp = pexpect.spawn( 'tail -f /tmp/s1-ofp.log' )
lp.expect( 'tcp:\d+\.\d+\.\d+\.(\d+):\d+: connected' )
ip = int( lp.match.group( 1 ) )
self.assertEqual( count, ip )
count += 1
for c in [ 'c0', 'c1' ]:
p.sendline( '%s ifconfig %s-eth0 down' % ( c, c) )
p.expect( self.prompt )
lp.expect( 'tcp:\d+\.\d+\.\d+\.(\d+):\d+: connected' )
ip = int( lp.match.group( 1 ) )
self.assertEqual( count, ip )
count += 1
p.sendline( 'exit' )
p.wait()
if __name__ == '__main__':
unittest.main()
-38
View File
@@ -1,38 +0,0 @@
#!/usr/bin/env python
"""
Test for cpu.py
"""
import unittest
import pexpect
import sys
class testCPU( unittest.TestCase ):
prompt = 'mininet>'
@unittest.skipIf( '-quick' in sys.argv, 'long test' )
def testCPU( self ):
"Verify that CPU utilization is monotonically decreasing for each scheduler"
p = pexpect.spawn( 'python -m mininet.examples.cpu' )
opts = [ '([a-z]+)\t([\d\.]+)%\t([\d\.]+)', pexpect.EOF ]
scheds = []
while True:
index = p.expect( opts, timeout=600 )
if index == 0:
sched = p.match.group( 1 )
cpu = float( p.match.group( 2 ) )
bw = float( p.match.group( 3 ) )
if sched not in scheds:
scheds.append( sched )
previous_bw = 10 ** 4 # 10 GB/s
self.assertTrue( bw < previous_bw )
previous_bw = bw
else:
break
self.assertTrue( len( scheds ) > 0 )
if __name__ == '__main__':
unittest.main()
-32
View File
@@ -1,32 +0,0 @@
#!/usr/bin/env python
"""
Test for emptynet.py
"""
import unittest
import pexpect
class testEmptyNet( unittest.TestCase ):
prompt = 'mininet>'
def testEmptyNet( self ):
"Run simple CLI tests: pingall (verify 0% drop) and iperf (sanity)"
p = pexpect.spawn( 'python -m mininet.examples.emptynet' )
p.expect( self.prompt )
# pingall test
p.sendline( 'pingall' )
p.expect ( '(\d+)% dropped' )
percent = int( p.match.group( 1 ) ) if p.match else -1
self.assertEqual( percent, 0 )
p.expect( self.prompt )
# iperf test
p.sendline( 'iperf' )
p.expect( "Results: \['[\d.]+ .bits/sec', '[\d.]+ .bits/sec'\]" )
p.expect( self.prompt )
p.sendline( 'exit' )
p.wait()
if __name__ == '__main__':
unittest.main()
-63
View File
@@ -1,63 +0,0 @@
#!/usr/bin/env python
"""
Test for hwintf.py
"""
import unittest
import pexpect
import re
from mininet.log import setLogLevel
from mininet.net import Mininet
from mininet.node import Node
from mininet.link import Link, Intf
class testHwintf( unittest.TestCase ):
prompt = 'mininet>'
def setUp( self ):
self.h3 = Node( 't0', ip='10.0.0.3/8' )
self.n0 = Node( 't1', inNamespace=False )
Link( self.h3, self.n0 )
self.h3.configDefault()
def testLocalPing( self ):
"Verify connectivity between virtual hosts using pingall"
p = pexpect.spawn( 'python -m mininet.examples.hwintf %s' % self.n0.intf() )
p.expect( self.prompt )
p.sendline( 'pingall' )
p.expect ( '(\d+)% dropped' )
percent = int( p.match.group( 1 ) ) if p.match else -1
self.assertEqual( percent, 0 )
p.expect( self.prompt )
p.sendline( 'exit' )
p.wait()
def testExternalPing( self ):
"Verify connnectivity between virtual host and virtual-physical 'external' host "
p = pexpect.spawn( 'python -m mininet.examples.hwintf %s' % self.n0.intf() )
p.expect( self.prompt )
# test ping external to internal
expectStr = '(\d+) packets transmitted, (\d+) received'
m = re.search( expectStr, self.h3.cmd( 'ping -v -c 1 10.0.0.1' ) )
tx = m.group( 1 )
rx = m.group( 2 )
self.assertEqual( tx, rx )
# test ping internal to external
p.sendline( 'h1 ping -c 1 10.0.0.3')
p.expect( expectStr )
tx = p.match.group( 1 )
rx = p.match.group( 2 )
self.assertEqual( tx, rx )
p.expect( self.prompt )
p.sendline( 'exit' )
p.wait()
def tearDown( self ):
self.h3.terminate()
self.n0.terminate()
if __name__ == '__main__':
setLogLevel( 'warning' )
unittest.main()
-40
View File
@@ -1,40 +0,0 @@
#!/usr/bin/env python
"""
Test for limit.py
"""
import unittest
import pexpect
import sys
class testLimit( unittest.TestCase ):
@unittest.skipIf( '-quick' in sys.argv, 'long test' )
def testLimit( self ):
"Verify that CPU limits are within a 2% tolerance of limit for each scheduler"
p = pexpect.spawn( 'python -m mininet.examples.limit' )
opts = [ '\*\*\* Testing network ([\d\.]+) Mbps',
'\*\*\* Results: \[([\d\., ]+)\]',
pexpect.EOF ]
count = 0
bw = 0
tolerance = 2
while True:
index = p.expect( opts )
if index == 0:
bw = float( p.match.group( 1 ) )
count += 1
elif index == 1:
results = p.match.group( 1 )
for x in results.split( ',' ):
result = float( x )
self.assertTrue( result < bw + tolerance )
self.assertTrue( result > bw - tolerance )
else:
break
self.assertTrue( count > 0 )
if __name__ == '__main__':
unittest.main()
-44
View File
@@ -1,44 +0,0 @@
#!/usr/bin/env python
"""
Test for linearbandwidth.py
"""
import unittest
import pexpect
import sys
class testLinearBandwidth( unittest.TestCase ):
@unittest.skipIf( '-quick' in sys.argv, 'long test' )
def testLinearBandwidth( self ):
"Verify that bandwidth is monotonically decreasing as # of hops increases"
p = pexpect.spawn( 'python -m mininet.examples.linearbandwidth' )
count = 0
opts = [ '\*\*\* Linear network results',
'(\d+)\s+([\d\.]+) (.bits)',
pexpect.EOF ]
while True:
index = p.expect( opts, timeout=600 )
if index == 0:
previous_bw = 10 ** 10 # 10 Gbits
count += 1
elif index == 1:
n = int( p.match.group( 1 ) )
bw = float( p.match.group( 2 ) )
unit = p.match.group( 3 )
if unit[ 0 ] == 'K':
bw *= 10 ** 3
elif unit[ 0 ] == 'M':
bw *= 10 ** 6
elif unit[ 0 ] == 'G':
bw *= 10 ** 9
self.assertTrue( bw < previous_bw )
previous_bw = bw
else:
break
self.assertTrue( count > 0 )
if __name__ == '__main__':
unittest.main()
-48
View File
@@ -1,48 +0,0 @@
#!/usr/bin/env python
"""
Test for multiping.py
"""
import unittest
import pexpect
from collections import defaultdict
class testMultiPing( unittest.TestCase ):
def testMultiPing( self ):
"""Verify that each target is pinged at least once, and
that pings to 'real' targets are successful and unknown targets fail"""
p = pexpect.spawn( 'python -m mininet.examples.multiping' )
opts = [ "Host (h\d+) \(([\d.]+)\) will be pinging ips: ([\d\. ]+)",
"(h\d+): ([\d.]+) -> ([\d.]+) \d packets transmitted, (\d) received",
pexpect.EOF ]
pings = defaultdict( list )
while True:
index = p.expect( opts )
if index == 0:
name = p.match.group(1)
ip = p.match.group(2)
targets = p.match.group(3).split()
pings[ name ] += targets
elif index == 1:
name = p.match.group(1)
ip = p.match.group(2)
target = p.match.group(3)
received = int( p.match.group(4) )
if target == '10.0.0.200':
self.assertEqual( received, 0 )
else:
self.assertEqual( received, 1 )
try:
pings[ name ].remove( target )
except:
pass
else:
break
self.assertTrue( len( pings ) > 0 )
for t in pings.values():
self.assertEqual( len( t ), 0 )
if __name__ == '__main__':
unittest.main()
-38
View File
@@ -1,38 +0,0 @@
#!/usr/bin/env python
"""
Test for multipoll.py
"""
import unittest
import pexpect
class testMultiPoll( unittest.TestCase ):
def testMultiPoll( self ):
"Verify that we receive one ping per second per host"
p = pexpect.spawn( 'python -m mininet.examples.multipoll' )
opts = [ "\*\*\* (h\d) :" ,
"(h\d+): \d+ bytes from",
"Monitoring output for (\d+) seconds",
pexpect.EOF ]
pings = {}
while True:
index = p.expect( opts )
if index == 0:
name = p.match.group( 1 )
pings[ name ] = 0
elif index == 1:
name = p.match.group( 1 )
pings[ name ] += 1
elif index == 2:
seconds = int( p.match.group( 1 ) )
else:
break
self.assertTrue( len( pings ) > 0 )
# make sure we have received at least one ping per second
for count in pings.values():
self.assertTrue( count >= seconds )
if __name__ == '__main__':
unittest.main()
-32
View File
@@ -1,32 +0,0 @@
#!/usr/bin/env python
"""
Test for multitest.py
"""
import unittest
import pexpect
class testMultiTest( unittest.TestCase ):
prompt = 'mininet>'
def testMultiTest( self ):
"Verify pingall (0% dropped) and hX-eth0 interface for each host (ifconfig)"
p = pexpect.spawn( 'python -m mininet.examples.multitest' )
p.expect( '(\d+)% dropped' )
dropped = int( p.match.group( 1 ) )
self.assertEqual( dropped, 0 )
ifCount = 0
while True:
index = p.expect( [ 'h\d-eth0', self.prompt ] )
if index == 0:
ifCount += 1
elif index == 1:
p.sendline( 'exit' )
break
p.wait()
self.assertEqual( ifCount, 4 )
if __name__ == '__main__':
unittest.main()
-32
View File
@@ -1,32 +0,0 @@
#!/usr/bin/env python
"""
Test for nat.py
"""
import unittest
import pexpect
from mininet.util import quietRun
destIP = '8.8.8.8' # Google DNS
class testNAT( unittest.TestCase ):
prompt = 'mininet>'
@unittest.skipIf( '0 received' in quietRun( 'ping -c 1 %s' % destIP ),
'Destination IP is not reachable' )
def testNAT( self ):
"Attempt to ping an IP on the Internet and verify 0% packet loss"
p = pexpect.spawn( 'python -m mininet.examples.nat' )
p.expect( self.prompt )
p.sendline( 'h1 ping -c 1 %s' % destIP )
p.expect ( '(\d+)% packet loss' )
percent = int( p.match.group( 1 ) ) if p.match else -1
p.expect( self.prompt )
p.sendline( 'exit' )
p.wait()
self.assertEqual( percent, 0 )
if __name__ == '__main__':
unittest.main()
-45
View File
@@ -1,45 +0,0 @@
#!/usr/bin/env python
"""
Test for popen.py and popenpoll.py
"""
import unittest
import pexpect
class testPopen( unittest.TestCase ):
def pingTest( self, name ):
"Verify that there are no dropped packets for each host"
p = pexpect.spawn( 'python -m %s' % name )
opts = [ "<(h\d+)>: PING ",
"<(h\d+)>: (\d+) packets transmitted, (\d+) received",
pexpect.EOF ]
pings = {}
while True:
index = p.expect( opts )
if index == 0:
name = p.match.group(1)
pings[ name ] = 0
elif index == 1:
name = p.match.group(1)
transmitted = p.match.group(2)
received = p.match.group(3)
# verify no dropped packets
self.assertEqual( received, transmitted )
pings[ name ] += 1
else:
break
self.assertTrue( len(pings) > 0 )
# verify that each host has gotten results
for count in pings.values():
self.assertEqual( count, 1 )
def testPopen( self ):
self.pingTest( 'mininet.examples.popen' )
def testPopenPoll( self ):
self.pingTest( 'mininet.examples.popenpoll' )
if __name__ == '__main__':
unittest.main()

Some files were not shown because too many files have changed in this diff Show More