Showing preview only (6,491K chars total). Download the full file or copy to clipboard to get everything.
Repository: superkkt/cherry
Branch: master
Commit: ea98d7c26dbc
Files: 698
Total size: 6.1 MB
Directory structure:
gitextract_s279x8yc/
├── .gitlab-ci.yml
├── Changelog
├── Dockerfile
├── Godeps/
│ ├── Godeps.json
│ └── Readme
├── Gopkg.toml
├── LICENSE
├── README.md
├── api/
│ ├── core/
│ │ └── api.go
│ ├── response.go
│ ├── server.go
│ └── ui/
│ ├── api.go
│ ├── category.go
│ ├── component.go
│ ├── group.go
│ ├── host.go
│ ├── ip.go
│ ├── log.go
│ ├── network.go
│ ├── session.go
│ ├── switch.go
│ ├── user.go
│ └── vip.go
├── cmd/
│ ├── cherry/
│ │ ├── cherry.yaml
│ │ └── main.go
│ └── walnut/
│ ├── main.go
│ ├── sdk.go
│ └── walnut.yaml
├── database/
│ ├── mysql.go
│ ├── mysql_schema.sql
│ └── random.go
├── election/
│ └── election.go
├── graph/
│ ├── graph.go
│ └── graph_test.go
├── ldap/
│ ├── client.go
│ └── conn.go
├── log/
│ └── syslog.go
├── network/
│ ├── controller.go
│ ├── device.go
│ ├── error.go
│ ├── flow_cache.go
│ ├── link.go
│ ├── node.go
│ ├── of10_session.go
│ ├── of13_session.go
│ ├── port.go
│ ├── reserve.go
│ ├── reserve_test.go
│ ├── session.go
│ └── topology.go
├── northbound/
│ ├── app/
│ │ ├── announcer/
│ │ │ ├── announcer.go
│ │ │ └── backoff.go
│ │ ├── dhcp/
│ │ │ └── dhcp.go
│ │ ├── discovery/
│ │ │ └── discovery.go
│ │ ├── l2switch/
│ │ │ ├── storm_controller.go
│ │ │ ├── storm_controller_test.go
│ │ │ └── switch.go
│ │ ├── monitor/
│ │ │ ├── monitor.go
│ │ │ └── sendmail.go
│ │ ├── processor.go
│ │ ├── proxyarp/
│ │ │ ├── arp.go
│ │ │ └── error.go
│ │ └── virtualip/
│ │ └── virtualip.go
│ └── manager.go
├── openflow/
│ ├── action.go
│ ├── barrier.go
│ ├── config.go
│ ├── const.go
│ ├── description.go
│ ├── echo.go
│ ├── error.go
│ ├── factory.go
│ ├── features.go
│ ├── flow_mod.go
│ ├── flow_removed.go
│ ├── flow_stats.go
│ ├── hello.go
│ ├── instruction.go
│ ├── match.go
│ ├── message.go
│ ├── of10/
│ │ ├── action.go
│ │ ├── barrier.go
│ │ ├── config.go
│ │ ├── const.go
│ │ ├── description.go
│ │ ├── echo.go
│ │ ├── factory.go
│ │ ├── features.go
│ │ ├── flow_mod.go
│ │ ├── flow_removed.go
│ │ ├── flow_stats.go
│ │ ├── hello.go
│ │ ├── instruction.go
│ │ ├── match.go
│ │ ├── packet_in.go
│ │ ├── packet_out.go
│ │ ├── port.go
│ │ ├── port_status.go
│ │ └── queue.go
│ ├── of13/
│ │ ├── action.go
│ │ ├── barrier.go
│ │ ├── config.go
│ │ ├── const.go
│ │ ├── echo.go
│ │ ├── factory.go
│ │ ├── features.go
│ │ ├── flow_mod.go
│ │ ├── flow_removed.go
│ │ ├── hello.go
│ │ ├── instruction.go
│ │ ├── match.go
│ │ ├── multipart_description.go
│ │ ├── multipart_flow_stats.go
│ │ ├── multipart_port_description.go
│ │ ├── multipart_table_features.go
│ │ ├── packet_in.go
│ │ ├── packet_out.go
│ │ ├── port.go
│ │ ├── port_status.go
│ │ └── queue.go
│ ├── packet_in.go
│ ├── packet_out.go
│ ├── port.go
│ ├── port_description.go
│ ├── port_status.go
│ ├── queue.go
│ ├── table_features.go
│ └── transceiver/
│ ├── stream.go
│ └── transceiver.go
├── protocol/
│ ├── arp.go
│ ├── checksum.go
│ ├── dhcp.go
│ ├── dhcp_test.go
│ ├── ethernet.go
│ ├── icmp.go
│ ├── ipv4.go
│ ├── lldp.go
│ ├── tcp.go
│ └── udp.go
├── vendor/
│ ├── github.com/
│ │ ├── ant0ine/
│ │ │ └── go-json-rest/
│ │ │ ├── LICENSE
│ │ │ └── rest/
│ │ │ ├── access_log_apache.go
│ │ │ ├── access_log_json.go
│ │ │ ├── api.go
│ │ │ ├── auth_basic.go
│ │ │ ├── content_type_checker.go
│ │ │ ├── cors.go
│ │ │ ├── doc.go
│ │ │ ├── gzip.go
│ │ │ ├── if.go
│ │ │ ├── json_indent.go
│ │ │ ├── jsonp.go
│ │ │ ├── middleware.go
│ │ │ ├── powered_by.go
│ │ │ ├── recorder.go
│ │ │ ├── recover.go
│ │ │ ├── request.go
│ │ │ ├── response.go
│ │ │ ├── route.go
│ │ │ ├── router.go
│ │ │ ├── status.go
│ │ │ ├── timer.go
│ │ │ └── trie/
│ │ │ └── impl.go
│ │ ├── boombuler/
│ │ │ └── barcode/
│ │ │ ├── .gitignore
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── barcode.go
│ │ │ ├── qr/
│ │ │ │ ├── alphanumeric.go
│ │ │ │ ├── automatic.go
│ │ │ │ ├── blocks.go
│ │ │ │ ├── encoder.go
│ │ │ │ ├── errorcorrection.go
│ │ │ │ ├── numeric.go
│ │ │ │ ├── qrcode.go
│ │ │ │ ├── unicode.go
│ │ │ │ └── versioninfo.go
│ │ │ ├── scaledbarcode.go
│ │ │ └── utils/
│ │ │ ├── base1dcode.go
│ │ │ ├── bitlist.go
│ │ │ ├── galoisfield.go
│ │ │ ├── gfpoly.go
│ │ │ ├── reedsolomon.go
│ │ │ └── runeint.go
│ │ ├── davecgh/
│ │ │ └── go-spew/
│ │ │ ├── LICENSE
│ │ │ └── spew/
│ │ │ ├── bypass.go
│ │ │ ├── bypasssafe.go
│ │ │ ├── common.go
│ │ │ ├── config.go
│ │ │ ├── doc.go
│ │ │ ├── dump.go
│ │ │ ├── format.go
│ │ │ └── spew.go
│ │ ├── fsnotify/
│ │ │ └── fsnotify/
│ │ │ ├── .gitignore
│ │ │ ├── .travis.yml
│ │ │ ├── AUTHORS
│ │ │ ├── CHANGELOG.md
│ │ │ ├── CONTRIBUTING.md
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── fen.go
│ │ │ ├── fsnotify.go
│ │ │ ├── inotify.go
│ │ │ ├── inotify_poller.go
│ │ │ ├── kqueue.go
│ │ │ ├── open_mode_bsd.go
│ │ │ ├── open_mode_darwin.go
│ │ │ └── windows.go
│ │ ├── go-sql-driver/
│ │ │ └── mysql/
│ │ │ ├── .gitignore
│ │ │ ├── .travis.yml
│ │ │ ├── AUTHORS
│ │ │ ├── CHANGELOG.md
│ │ │ ├── CONTRIBUTING.md
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── appengine.go
│ │ │ ├── buffer.go
│ │ │ ├── collations.go
│ │ │ ├── connection.go
│ │ │ ├── connection_go18.go
│ │ │ ├── const.go
│ │ │ ├── driver.go
│ │ │ ├── dsn.go
│ │ │ ├── errors.go
│ │ │ ├── fields.go
│ │ │ ├── infile.go
│ │ │ ├── packets.go
│ │ │ ├── result.go
│ │ │ ├── rows.go
│ │ │ ├── statement.go
│ │ │ ├── transaction.go
│ │ │ ├── utils.go
│ │ │ ├── utils_go17.go
│ │ │ └── utils_go18.go
│ │ ├── google/
│ │ │ └── go-cmp/
│ │ │ ├── LICENSE
│ │ │ └── cmp/
│ │ │ ├── cmpopts/
│ │ │ │ ├── equate.go
│ │ │ │ ├── ignore.go
│ │ │ │ ├── sort.go
│ │ │ │ ├── struct_filter.go
│ │ │ │ └── xform.go
│ │ │ ├── compare.go
│ │ │ ├── export_panic.go
│ │ │ ├── export_unsafe.go
│ │ │ ├── internal/
│ │ │ │ ├── diff/
│ │ │ │ │ ├── debug_disable.go
│ │ │ │ │ ├── debug_enable.go
│ │ │ │ │ └── diff.go
│ │ │ │ ├── flags/
│ │ │ │ │ ├── flags.go
│ │ │ │ │ ├── toolchain_legacy.go
│ │ │ │ │ └── toolchain_recent.go
│ │ │ │ ├── function/
│ │ │ │ │ └── func.go
│ │ │ │ └── value/
│ │ │ │ ├── pointer_purego.go
│ │ │ │ ├── pointer_unsafe.go
│ │ │ │ ├── sort.go
│ │ │ │ └── zero.go
│ │ │ ├── options.go
│ │ │ ├── path.go
│ │ │ ├── report.go
│ │ │ ├── report_compare.go
│ │ │ ├── report_reflect.go
│ │ │ ├── report_slices.go
│ │ │ ├── report_text.go
│ │ │ └── report_value.go
│ │ ├── hashicorp/
│ │ │ ├── golang-lru/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── 2q.go
│ │ │ │ ├── LICENSE
│ │ │ │ ├── README.md
│ │ │ │ ├── arc.go
│ │ │ │ ├── lru.go
│ │ │ │ └── simplelru/
│ │ │ │ └── lru.go
│ │ │ └── hcl/
│ │ │ ├── .gitignore
│ │ │ ├── .travis.yml
│ │ │ ├── LICENSE
│ │ │ ├── Makefile
│ │ │ ├── README.md
│ │ │ ├── appveyor.yml
│ │ │ ├── decoder.go
│ │ │ ├── hcl/
│ │ │ │ ├── ast/
│ │ │ │ │ ├── ast.go
│ │ │ │ │ └── walk.go
│ │ │ │ ├── parser/
│ │ │ │ │ ├── error.go
│ │ │ │ │ └── parser.go
│ │ │ │ ├── scanner/
│ │ │ │ │ └── scanner.go
│ │ │ │ ├── strconv/
│ │ │ │ │ └── quote.go
│ │ │ │ └── token/
│ │ │ │ ├── position.go
│ │ │ │ └── token.go
│ │ │ ├── hcl.go
│ │ │ ├── json/
│ │ │ │ ├── parser/
│ │ │ │ │ ├── flatten.go
│ │ │ │ │ └── parser.go
│ │ │ │ ├── scanner/
│ │ │ │ │ └── scanner.go
│ │ │ │ └── token/
│ │ │ │ ├── position.go
│ │ │ │ └── token.go
│ │ │ ├── lex.go
│ │ │ └── parse.go
│ │ ├── magiconair/
│ │ │ └── properties/
│ │ │ ├── .gitignore
│ │ │ ├── .travis.yml
│ │ │ ├── CHANGELOG.md
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── _third_party/
│ │ │ │ └── gopkg.in/
│ │ │ │ └── check.v1/
│ │ │ │ └── LICENSE
│ │ │ ├── decode.go
│ │ │ ├── doc.go
│ │ │ ├── integrate.go
│ │ │ ├── lex.go
│ │ │ ├── load.go
│ │ │ ├── parser.go
│ │ │ ├── properties.go
│ │ │ └── rangecheck.go
│ │ ├── mitchellh/
│ │ │ └── mapstructure/
│ │ │ ├── .travis.yml
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── decode_hooks.go
│ │ │ ├── error.go
│ │ │ └── mapstructure.go
│ │ ├── pelletier/
│ │ │ ├── go-buffruneio/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── .travis.yml
│ │ │ │ ├── README.md
│ │ │ │ └── buffruneio.go
│ │ │ └── go-toml/
│ │ │ ├── .gitignore
│ │ │ ├── .travis.yml
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── clean.sh
│ │ │ ├── doc.go
│ │ │ ├── example-crlf.toml
│ │ │ ├── example.toml
│ │ │ ├── keysparsing.go
│ │ │ ├── lexer.go
│ │ │ ├── match.go
│ │ │ ├── parser.go
│ │ │ ├── position.go
│ │ │ ├── query.go
│ │ │ ├── querylexer.go
│ │ │ ├── queryparser.go
│ │ │ ├── test.sh
│ │ │ ├── token.go
│ │ │ ├── toml.go
│ │ │ └── tomltree_conversions.go
│ │ ├── pkg/
│ │ │ └── errors/
│ │ │ ├── .gitignore
│ │ │ ├── .travis.yml
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── appveyor.yml
│ │ │ ├── errors.go
│ │ │ └── stack.go
│ │ ├── pquerna/
│ │ │ └── otp/
│ │ │ ├── .travis.yml
│ │ │ ├── LICENSE
│ │ │ ├── NOTICE
│ │ │ ├── README.md
│ │ │ ├── doc.go
│ │ │ ├── hotp/
│ │ │ │ └── hotp.go
│ │ │ ├── otp.go
│ │ │ └── totp/
│ │ │ └── totp.go
│ │ ├── spf13/
│ │ │ ├── afero/
│ │ │ │ ├── .travis.yml
│ │ │ │ ├── LICENSE.txt
│ │ │ │ ├── README.md
│ │ │ │ ├── afero.go
│ │ │ │ ├── appveyor.yml
│ │ │ │ ├── basepath.go
│ │ │ │ ├── cacheOnReadFs.go
│ │ │ │ ├── const_bsds.go
│ │ │ │ ├── const_win_unix.go
│ │ │ │ ├── copyOnWriteFs.go
│ │ │ │ ├── httpFs.go
│ │ │ │ ├── ioutil.go
│ │ │ │ ├── mem/
│ │ │ │ │ ├── dir.go
│ │ │ │ │ ├── dirmap.go
│ │ │ │ │ └── file.go
│ │ │ │ ├── memmap.go
│ │ │ │ ├── memradix.go
│ │ │ │ ├── os.go
│ │ │ │ ├── path.go
│ │ │ │ ├── readonlyfs.go
│ │ │ │ ├── regexpfs.go
│ │ │ │ ├── unionFile.go
│ │ │ │ └── util.go
│ │ │ ├── cast/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── LICENSE
│ │ │ │ ├── README.md
│ │ │ │ ├── cast.go
│ │ │ │ └── caste.go
│ │ │ ├── jwalterweatherman/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── LICENSE
│ │ │ │ ├── README.md
│ │ │ │ └── thatswhyyoualwaysleaveanote.go
│ │ │ └── pflag/
│ │ │ ├── .travis.yml
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── bool.go
│ │ │ ├── count.go
│ │ │ ├── duration.go
│ │ │ ├── flag.go
│ │ │ ├── float32.go
│ │ │ ├── float64.go
│ │ │ ├── golangflag.go
│ │ │ ├── int.go
│ │ │ ├── int32.go
│ │ │ ├── int64.go
│ │ │ ├── int8.go
│ │ │ ├── int_slice.go
│ │ │ ├── ip.go
│ │ │ ├── ipmask.go
│ │ │ ├── ipnet.go
│ │ │ ├── string.go
│ │ │ ├── string_slice.go
│ │ │ ├── uint.go
│ │ │ ├── uint16.go
│ │ │ ├── uint32.go
│ │ │ ├── uint64.go
│ │ │ └── uint8.go
│ │ └── superkkt/
│ │ ├── go-logging/
│ │ │ ├── .travis.yml
│ │ │ ├── CHANGELOG.md
│ │ │ ├── CONTRIBUTORS
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── backend.go
│ │ │ ├── format.go
│ │ │ ├── level.go
│ │ │ ├── log_nix.go
│ │ │ ├── log_windows.go
│ │ │ ├── logger.go
│ │ │ ├── memory.go
│ │ │ ├── multi.go
│ │ │ ├── syslog.go
│ │ │ └── syslog_fallback.go
│ │ └── viper/
│ │ ├── .gitignore
│ │ ├── .travis.yml
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── flags.go
│ │ ├── nohup.out
│ │ ├── util.go
│ │ └── viper.go
│ ├── golang.org/
│ │ └── x/
│ │ ├── sys/
│ │ │ ├── AUTHORS
│ │ │ ├── CONTRIBUTORS
│ │ │ ├── LICENSE
│ │ │ ├── PATENTS
│ │ │ └── unix/
│ │ │ ├── .gitignore
│ │ │ ├── asm.s
│ │ │ ├── asm_darwin_386.s
│ │ │ ├── asm_darwin_amd64.s
│ │ │ ├── asm_darwin_arm.s
│ │ │ ├── asm_darwin_arm64.s
│ │ │ ├── asm_dragonfly_amd64.s
│ │ │ ├── asm_freebsd_386.s
│ │ │ ├── asm_freebsd_amd64.s
│ │ │ ├── asm_freebsd_arm.s
│ │ │ ├── asm_linux_386.s
│ │ │ ├── asm_linux_amd64.s
│ │ │ ├── asm_linux_arm.s
│ │ │ ├── asm_linux_arm64.s
│ │ │ ├── asm_linux_mips64x.s
│ │ │ ├── asm_linux_ppc64x.s
│ │ │ ├── asm_linux_s390x.s
│ │ │ ├── asm_netbsd_386.s
│ │ │ ├── asm_netbsd_amd64.s
│ │ │ ├── asm_netbsd_arm.s
│ │ │ ├── asm_openbsd_386.s
│ │ │ ├── asm_openbsd_amd64.s
│ │ │ ├── asm_solaris_amd64.s
│ │ │ ├── bluetooth_linux.go
│ │ │ ├── constants.go
│ │ │ ├── env_unix.go
│ │ │ ├── env_unset.go
│ │ │ ├── flock.go
│ │ │ ├── flock_linux_32bit.go
│ │ │ ├── gccgo.go
│ │ │ ├── gccgo_c.c
│ │ │ ├── gccgo_linux_amd64.go
│ │ │ ├── mkall.sh
│ │ │ ├── mkerrors.sh
│ │ │ ├── mkpost.go
│ │ │ ├── mksyscall.pl
│ │ │ ├── mksyscall_solaris.pl
│ │ │ ├── mksysctl_openbsd.pl
│ │ │ ├── mksysnum_darwin.pl
│ │ │ ├── mksysnum_dragonfly.pl
│ │ │ ├── mksysnum_freebsd.pl
│ │ │ ├── mksysnum_linux.pl
│ │ │ ├── mksysnum_netbsd.pl
│ │ │ ├── mksysnum_openbsd.pl
│ │ │ ├── race.go
│ │ │ ├── race0.go
│ │ │ ├── sockcmsg_linux.go
│ │ │ ├── sockcmsg_unix.go
│ │ │ ├── str.go
│ │ │ ├── syscall.go
│ │ │ ├── syscall_bsd.go
│ │ │ ├── syscall_darwin.go
│ │ │ ├── syscall_darwin_386.go
│ │ │ ├── syscall_darwin_amd64.go
│ │ │ ├── syscall_darwin_arm.go
│ │ │ ├── syscall_darwin_arm64.go
│ │ │ ├── syscall_dragonfly.go
│ │ │ ├── syscall_dragonfly_amd64.go
│ │ │ ├── syscall_freebsd.go
│ │ │ ├── syscall_freebsd_386.go
│ │ │ ├── syscall_freebsd_amd64.go
│ │ │ ├── syscall_freebsd_arm.go
│ │ │ ├── syscall_linux.go
│ │ │ ├── syscall_linux_386.go
│ │ │ ├── syscall_linux_amd64.go
│ │ │ ├── syscall_linux_arm.go
│ │ │ ├── syscall_linux_arm64.go
│ │ │ ├── syscall_linux_mips64x.go
│ │ │ ├── syscall_linux_ppc64x.go
│ │ │ ├── syscall_linux_s390x.go
│ │ │ ├── syscall_netbsd.go
│ │ │ ├── syscall_netbsd_386.go
│ │ │ ├── syscall_netbsd_amd64.go
│ │ │ ├── syscall_netbsd_arm.go
│ │ │ ├── syscall_no_getwd.go
│ │ │ ├── syscall_openbsd.go
│ │ │ ├── syscall_openbsd_386.go
│ │ │ ├── syscall_openbsd_amd64.go
│ │ │ ├── syscall_solaris.go
│ │ │ ├── syscall_solaris_amd64.go
│ │ │ ├── syscall_unix.go
│ │ │ ├── types_darwin.go
│ │ │ ├── types_dragonfly.go
│ │ │ ├── types_freebsd.go
│ │ │ ├── types_linux.go
│ │ │ ├── types_netbsd.go
│ │ │ ├── types_openbsd.go
│ │ │ ├── types_solaris.go
│ │ │ ├── zerrors_darwin_386.go
│ │ │ ├── zerrors_darwin_amd64.go
│ │ │ ├── zerrors_darwin_arm.go
│ │ │ ├── zerrors_darwin_arm64.go
│ │ │ ├── zerrors_dragonfly_amd64.go
│ │ │ ├── zerrors_freebsd_386.go
│ │ │ ├── zerrors_freebsd_amd64.go
│ │ │ ├── zerrors_freebsd_arm.go
│ │ │ ├── zerrors_linux_386.go
│ │ │ ├── zerrors_linux_amd64.go
│ │ │ ├── zerrors_linux_arm.go
│ │ │ ├── zerrors_linux_arm64.go
│ │ │ ├── zerrors_linux_mips64.go
│ │ │ ├── zerrors_linux_mips64le.go
│ │ │ ├── zerrors_linux_ppc64.go
│ │ │ ├── zerrors_linux_ppc64le.go
│ │ │ ├── zerrors_linux_s390x.go
│ │ │ ├── zerrors_netbsd_386.go
│ │ │ ├── zerrors_netbsd_amd64.go
│ │ │ ├── zerrors_netbsd_arm.go
│ │ │ ├── zerrors_openbsd_386.go
│ │ │ ├── zerrors_openbsd_amd64.go
│ │ │ ├── zerrors_solaris_amd64.go
│ │ │ ├── zsyscall_darwin_386.go
│ │ │ ├── zsyscall_darwin_amd64.go
│ │ │ ├── zsyscall_darwin_arm.go
│ │ │ ├── zsyscall_darwin_arm64.go
│ │ │ ├── zsyscall_dragonfly_amd64.go
│ │ │ ├── zsyscall_freebsd_386.go
│ │ │ ├── zsyscall_freebsd_amd64.go
│ │ │ ├── zsyscall_freebsd_arm.go
│ │ │ ├── zsyscall_linux_386.go
│ │ │ ├── zsyscall_linux_amd64.go
│ │ │ ├── zsyscall_linux_arm.go
│ │ │ ├── zsyscall_linux_arm64.go
│ │ │ ├── zsyscall_linux_mips64.go
│ │ │ ├── zsyscall_linux_mips64le.go
│ │ │ ├── zsyscall_linux_ppc64.go
│ │ │ ├── zsyscall_linux_ppc64le.go
│ │ │ ├── zsyscall_linux_s390x.go
│ │ │ ├── zsyscall_netbsd_386.go
│ │ │ ├── zsyscall_netbsd_amd64.go
│ │ │ ├── zsyscall_netbsd_arm.go
│ │ │ ├── zsyscall_openbsd_386.go
│ │ │ ├── zsyscall_openbsd_amd64.go
│ │ │ ├── zsyscall_solaris_amd64.go
│ │ │ ├── zsysctl_openbsd.go
│ │ │ ├── zsysnum_darwin_386.go
│ │ │ ├── zsysnum_darwin_amd64.go
│ │ │ ├── zsysnum_darwin_arm.go
│ │ │ ├── zsysnum_darwin_arm64.go
│ │ │ ├── zsysnum_dragonfly_amd64.go
│ │ │ ├── zsysnum_freebsd_386.go
│ │ │ ├── zsysnum_freebsd_amd64.go
│ │ │ ├── zsysnum_freebsd_arm.go
│ │ │ ├── zsysnum_linux_386.go
│ │ │ ├── zsysnum_linux_amd64.go
│ │ │ ├── zsysnum_linux_arm.go
│ │ │ ├── zsysnum_linux_arm64.go
│ │ │ ├── zsysnum_linux_mips64.go
│ │ │ ├── zsysnum_linux_mips64le.go
│ │ │ ├── zsysnum_linux_ppc64.go
│ │ │ ├── zsysnum_linux_ppc64le.go
│ │ │ ├── zsysnum_linux_s390x.go
│ │ │ ├── zsysnum_netbsd_386.go
│ │ │ ├── zsysnum_netbsd_amd64.go
│ │ │ ├── zsysnum_netbsd_arm.go
│ │ │ ├── zsysnum_openbsd_386.go
│ │ │ ├── zsysnum_openbsd_amd64.go
│ │ │ ├── zsysnum_solaris_amd64.go
│ │ │ ├── ztypes_darwin_386.go
│ │ │ ├── ztypes_darwin_amd64.go
│ │ │ ├── ztypes_darwin_arm.go
│ │ │ ├── ztypes_darwin_arm64.go
│ │ │ ├── ztypes_dragonfly_amd64.go
│ │ │ ├── ztypes_freebsd_386.go
│ │ │ ├── ztypes_freebsd_amd64.go
│ │ │ ├── ztypes_freebsd_arm.go
│ │ │ ├── ztypes_linux_386.go
│ │ │ ├── ztypes_linux_amd64.go
│ │ │ ├── ztypes_linux_arm.go
│ │ │ ├── ztypes_linux_arm64.go
│ │ │ ├── ztypes_linux_mips64.go
│ │ │ ├── ztypes_linux_mips64le.go
│ │ │ ├── ztypes_linux_ppc64.go
│ │ │ ├── ztypes_linux_ppc64le.go
│ │ │ ├── ztypes_linux_s390x.go
│ │ │ ├── ztypes_netbsd_386.go
│ │ │ ├── ztypes_netbsd_amd64.go
│ │ │ ├── ztypes_netbsd_arm.go
│ │ │ ├── ztypes_openbsd_386.go
│ │ │ ├── ztypes_openbsd_amd64.go
│ │ │ └── ztypes_solaris_amd64.go
│ │ └── text/
│ │ ├── AUTHORS
│ │ ├── CONTRIBUTORS
│ │ ├── LICENSE
│ │ ├── PATENTS
│ │ ├── internal/
│ │ │ ├── gen/
│ │ │ │ ├── code.go
│ │ │ │ └── gen.go
│ │ │ ├── triegen/
│ │ │ │ ├── compact.go
│ │ │ │ ├── print.go
│ │ │ │ └── triegen.go
│ │ │ └── ucd/
│ │ │ └── ucd.go
│ │ ├── transform/
│ │ │ └── transform.go
│ │ └── unicode/
│ │ ├── cldr/
│ │ │ ├── base.go
│ │ │ ├── cldr.go
│ │ │ ├── collate.go
│ │ │ ├── decode.go
│ │ │ ├── makexml.go
│ │ │ ├── resolve.go
│ │ │ ├── slice.go
│ │ │ └── xml.go
│ │ └── norm/
│ │ ├── composition.go
│ │ ├── forminfo.go
│ │ ├── input.go
│ │ ├── iter.go
│ │ ├── maketables.go
│ │ ├── normalize.go
│ │ ├── readwriter.go
│ │ ├── tables.go
│ │ ├── transform.go
│ │ ├── trie.go
│ │ └── triegen.go
│ ├── google.golang.org/
│ │ └── appengine/
│ │ ├── LICENSE
│ │ └── cloudsql/
│ │ ├── cloudsql.go
│ │ ├── cloudsql_classic.go
│ │ └── cloudsql_vm.go
│ └── gopkg.in/
│ ├── asn1-ber.v1/
│ │ ├── .travis.yml
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── ber.go
│ │ ├── content_int.go
│ │ ├── header.go
│ │ ├── identifier.go
│ │ ├── length.go
│ │ └── util.go
│ ├── ldap.v3/
│ │ ├── .gitignore
│ │ ├── .travis.yml
│ │ ├── CONTRIBUTING.md
│ │ ├── LICENSE
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── add.go
│ │ ├── bind.go
│ │ ├── client.go
│ │ ├── compare.go
│ │ ├── conn.go
│ │ ├── control.go
│ │ ├── debug.go
│ │ ├── del.go
│ │ ├── dn.go
│ │ ├── doc.go
│ │ ├── error.go
│ │ ├── filter.go
│ │ ├── ldap.go
│ │ ├── moddn.go
│ │ ├── modify.go
│ │ ├── passwdmodify.go
│ │ └── search.go
│ └── yaml.v2/
│ ├── .travis.yml
│ ├── LICENSE
│ ├── LICENSE.libyaml
│ ├── README.md
│ ├── apic.go
│ ├── decode.go
│ ├── emitterc.go
│ ├── encode.go
│ ├── parserc.go
│ ├── readerc.go
│ ├── resolve.go
│ ├── scannerc.go
│ ├── sorter.go
│ ├── writerc.go
│ ├── yaml.go
│ ├── yamlh.go
│ └── yamlprivateh.go
└── version.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitlab-ci.yml
================================================
image: golang:1.12
before_script:
- mkdir -p /go/src/github.com/superkkt
- cp -rp /builds/superkkt/cherry /go/src/github.com/superkkt
stages:
- build
- test
build_all:
stage: build
script:
- cd /go/src/github.com/superkkt/cherry
- go build $(go list ./... | grep -v /vendor/)
test_all:
stage: test
script:
- cd /go/src/github.com/superkkt/cherry
- go test $(go list ./... | grep -v /vendor/)
================================================
FILE: Changelog
================================================
* v0.14.2 (2019-09-20)
3faead4 Fix the unexpected master change (See #44)
* v0.14.1 (2019-09-03)
b321987 Remove password plain text log (See #43)
* v0.14.0 (2019-08-02)
fad9247 Change ui server middleware order (See #42)
e02444b Change name of host table timestamp column (See #41)
7ee607a Revert "Set hard-timeout to clear stale flows"
71199c6 Change data column type in log table (See #38)
3b8fe3e Apply LDAP (See #31)
715f48f Change validation of input length (See #36)
6a81a12 Change timestamp column option in host table (See #37)
9cf45b8 Apply TOTP (See #30)
6f28b01 Prevent gateway from being set as reserved IP (See #35)
4faeba4 Change host update API (See #26)
efaab76 Change IP structure (See #27)
8f0eb70 Add get host API (See #34)
040d871 Add gateway within network (See #25)
501c3d3 Add network search (See #24)
8740e05 Add spec feature within host (See #29)
2e8ed92 Add Component UI API (See #28)
3f301a2 Add Category UI API (See #23)
80606bb Add Log UI API (See #18)
519ecce Fix a bug to add an invalid IP address to the database when adding a network (See #33)
c4c6fdf NULL MAC address to disconnect a host from the network (See #32)
3504fd6 Dedicated IP address for ARP host discovery (See #12)
cb92e4a Use reserved IP addresses (TEST-NET-1) for DHCP and ARP discovery
79d95da Validate TCP and UDP packet lengths
a5415ba Fix the broken UDP checksum
6ce8b01 Implement a DHCP server
c01b487 refactoring: apply the custom response writer to the UI API
cf82a97 revise
abf5e1a refactoring: apply pagination with structure
fbf94f0 refactoring: ui transaction returns instance reference
936f21d Add Host List API (See #20)
74ff82e fix add, update host
9e013c9 refactoring: call database logics in a closure
b9b85d4 refactoring: apply the custom response writer to the core API
726f009 refactoring: custom response writer with logging
58362ed Add Host UI API (See #20)
c31fdaa Add VIP UI API (See #19)
a13a7dc Refactoring: re-organize the source tree structure of the API package
5667f06 Add Switch UI API (See #14)
0090f4b Add Network UI API (See #15)
1729ffa Add Host group UI API (See #17)
4e4188f Add User UI API (See #16)
b10bfa7 Add extra comment for time interval of the flow manager
a4aaac9 Set hard-timeout to clear stale flows
0c939a7 ARP announcer (See #22)
cd32572 Devide UI API server (See #13)
9af1b5b Fix the broken test case
e2e8add Replace godep with dep to vendor libraries
9cddf5f Add extra debug logs for broadcast packets
b1e6584 Update the buffered socket stream to avoid a potential internal buffer corruption
ef776e5 Add the GitLab CI
f4f235f Fix a typo
1fa1d05 Fix broken test cases
146b172 Fix the IP conflict by ARP probes (See #12)
* v0.13.5 (2018-05-15)
06fe675 Discovery: workaround for old OSes that have a broken TCP/IP stack (See #6)
* v0.13.4 (2018-04-22)
4767d4c Fix the node discovery bug (See #5)
* v0.13.3 (2018-04-22)
619eefc Revert "Decrease the PACKET_IN read buffer size"
* v0.13.2 (2018-04-20)
05f3fc0 Adjust log levels
412988e Use string parameters in the YAML config file
1114081 MySQL: validate the cluster address
fe7f912 Update the MySQL driver
c3b6288 mysql: new cluster dialer and query function that pass Tx instead of DB
a760e5e Ignore the WRITE fsnotify operation to avoid reading empty config
d4d48f7 Increase the flow idle timeout
df3e5ed Make a switch drops all incoming packets (except ARP and LLDP) for a while on start up
0bfdb5b Sort networks by address
3809a8c Re-ordering DB tables in the MySQL schema
9eb8066 Decrease the ARP probe interval
480d6b5 Fix missing time interval change
7cfdccb Decrease the flow manager interval
6f8780c Add extra comments
151ab37 Decrease the device explorer interval to 1 minute
0e11b0d Update a debug message
1fc910c Decrease ARP sender's loop interval to 1.5 sec.
5472f62 Add a comment for time buffering
750627a Drop the some PACKET_INs for proper device setup on start up
0670200 Drop the packets before ethernet parsing if the device is not yet ready
e7d0e91 Decrease ARP sender's loop interval
3f3fbc3 Send ARP probes immediately on start up for fast discovery
a77d304 Fix aaa0e4fd797 as OF1.0 does not support the cookie mask
5ade735 Deny the API request if we are not the master controller
5e2633e Keep the ARP flow unless the switch device reconnects
aaa0e4f Flow cache to avoid duplicate and repeated flow installation (See #1)
f8bb64f Minor refactoring
109e393 Refactoring of the switch device negotiation procedure
c527c28 Add extra debug messages
e8d4b50 Decrease the timeout for a staled host
6d42974 Decrease the PACKET_IN read buffer size
78f098a Use FLOW_ADD instead of FLOW_MODIFY for a broken switch device (i.e., Dell S3148) (See #1)
7770802 Log DPID when we get an openflow error packet
018b460 Ignore the invalid echo responses
* v0.13.1 (Sat Aug 05 16:45:00 2017 +0900)
075e31c Ignore the ARP reply received from an edge among switches
* v0.13.0 (Fri Aug 04 23:37:48 2017 +0900)
fe412ce Remove duplicated link down check
5bfbf68 Decrease the flow manager interval to 1 minute
0130939 Flow manager to keep the flows update
b92618c Fix the deadlock between the topology and the device
698ce6a Minor refactoring
7a88c77 Set idle and hard flow timeouts from the config
ae4e791 Log flow removed timestamp
13ba29f Remove all the flow histories on the device down event
fd8b1a4 Warning log on the port down event
72b66c2 Backoff-delayed ARP announcer for all the registered hosts
fbc8759 Backoff-delayed ARP announcer
0509b0c Invalidate the ARP caches when a host is removed
9d0500e Fix the broken VIP toggling by repeated toggles in a moment
d468086 Minor refactoring of README
f7cee84 Update README for the new configuration file
ae3ee97 Fix the broken VIP toggling by the Discovery module
ad5b2d9 Revert a weird patch 601ac8055
ce25c01 Minor refactoring by function renaming
daaeaed Log switch device up/down events
a34bdce Fix the broken Dockerfile
ee8f7a4 Flow history on the database
e46bce5 Adjust switch port numbers based on its first printed port number
b8eb6e9 Dynamic config reloading
0a3a53f Increase log level of toggling VIP addresses
5841fd6 Remove the old Golang X Context package
9c62ce2 Fix the unintended package import
a014cee Adjust log message level
38bbac7 Implement automatic master election
0be0c21 New host stale field instead of its UNIX timestamp
584e230 Minor refactoring
31e2491 Adjust loop intervals
4acb3e3 Remove useless comment
a5b152e Periodic switch port scanning
bef4a14 Minor refactoring for the device expolorer interval
aee62af Periodically send LLDPs to keep the network topology updated
a730b7e Dynamic discovery of physical host locations using the ARP probe
67911b1 Fix unexpected foreign key error from deleting a network address
bba56c1 Add debug messages for ECHO_REQUEST and ECHO_REPLY packets
e0b7e53 Decrease the capacity of the reader channel
* v0.12.1 (Wed Aug 31 15:06:31 2016 +0900)
3d35bfb Log the number of unread remaining packets in the reader channel
e1cfa8b Ignore soft errors from OpenFlow EchoReply
6d6e729 Fix the incorrect log levels of the config file
* v0.12.0 (Sun Aug 28 18:57:08 2016 +0900)
46a636c Fix the bug caused by unnecessary protocol vercion checking
e40cda8 Run the packet reader thread in the OpenFlow transceiver
6a16954 Rename the openflow/trans package to openflow/transceiver
14fd96d Replace the custom logger with the go-logging library
b5ca266 Reorganize the package structure
9f48eb6 Adopt a temporary error to ignore soft errors
b522598 Vendoring by Godeps
a107e1f Do not support multiple DB hosts and set the wait_time MySQL variable to 120s
* v0.11.0 (Mon Jun 6 15:42:29 2016 +0900)
4599801 (HEAD, tag: v0.11.0, origin/v0.11, origin/master, origin/HEAD, v0.11, master) Bump version to 0.11.0
601ac80 Fix the duplicated DPID by disconnecting the previous main connection (see #8313)
2cb100e Vendoring all libraries
21b7e2f Update Changelog and LICENSE
4797aa3 Change version to 0.11-RC3
6700906 Send the alarm email asynchronously (see #6547)
c21420a Change version to 0.11-RC2
25ac489 Enable the monitor app (see #6547)
f26e497 Change version to 0.11-RC
29f152a Implement notification when a device is up and down (see #6547)
* v0.10.0 (Sat Oct 24 17:57:16 2015 +0900)
18fb269 (tag: v0.10.0, origin/v0.10) Change version to 0.10-RC
87b02be Implement a broadcast storm controller (see #6534)
59c98c0 Add version flag
* v0.9.1 (Tue Oct 20 22:28:58 2015 +0900)
9a00866 (tag: v0.9.1, origin/v0.9) Implement a flow cache to avoid duplicated flow installation
4299780 Remove hard timeout of a L2 switch's flow
07ee1e2 Add the version flag
* v0.9.0 (Fri Oct 9 00:34:00 2015 +0900)
35a345c (tag: v0.9.0) Update README.md
1650f6a Update README.md
3310bcc Add Changelog
2933299 Add origin header
3ee079f Improve VIP toggling logs
d305027 Remove useless modules
b66bcb3 Remove foreign key delete cascade as MySQL does not call triggers on the cascding
e471dbc Implement manual toggle VIP active/standby hosts (see #6109)
38f8be4 Drop useless removing flows when removeVIP API is called
211df46 Add VIP toggle log messages
a2ea75e Fix incorrect query string
4f383e3 Add VIPParam validation
db7db86 Minor refactoring
d24b64d Implement floating virtual IP (see #6109)
34c7956 Improve MAC address handling of the REST module
e0eaced Fix incorrect IP and MAC parser and add log messages
7c762a2 Fix decoding MAC address routine that results in panic
5ef7ab8 Implement host list, add, and remove REST APIs
c2a5f0f Refactoring of REST APIs
2aa69f3 Implement network list, add, and delete APIs via REST
66469a1 Change default REST port number from 8080 to 7070
06b7fad Implement switch list, add, and delete APIs via REST
91b9b28 Do not return error if we cannot find a neighbor device or its port to avoid unexpected device disconnection
a82d8df Send barrier reqeust after setting ARP sender flow
1a88dd4 Remove incorrect log message of ProxyARP
4d42ee8 Improve ARP announcement checker
6c732c3 Allow database connection error if there is at least one avaliable server on the database pool (see #6236)
22e6838 Log malicious ARP packet whose ethernet destination MAC is not the broadcast address
1570025 Refactoring ARP sender flow routines
f82246b Add a permanent flow for ARP packets to forward them to the controller
545625b Improve DB index
259e06d Improve DB indices
4a81851 Fix incorrect unique keys of host DB table
5558f15 Make DB DELETE to be cascaded
b03ea16 Add host description field to the database schema
4d7fcbf Implement multiple database connections (see #6115)
b44a7b6 Check ARP announcement before ARP operation (see #6109)
0ba70d7 Drop ARP announcement packets (see #6109)
3d31799 Fix typo
ac588a8 Implement ARP packet description
ceb047a Remove useless assigning of return values (see #6104)
c7935d6 Implement MySQL deadlock protection (see #6104)
4959db7 Add OFPFF_CHECK_OVERLAP flag to FLOW_MOD (see #6108)
1037c73 Change host DB table schema
253cf47 Remove flows when port down event is detected (see #6108)
90da465 Implement fixed host location (see #6103)
3827e3d Clear all learned MAC addresses when the topology is updated (see #6102)
d5e0bde Fix incorrect Deadline interface
0832255 Remove ARP announcement routines from the ProxyARP module
691a2db Remove the router module
9676380 Implement VLAN ID of the OpenFlow action
94dd8e6 Add the router module
fd3eb21 Implement per-device host database in the topology
9ac9595 Remove the router northbound application
ecd84f5 Implement InPort output action
136ee97 Fix missing IP ToS wildcard
6ced806 Fix incorrect IPv4 address handling
7961ab5 Implement SetEnqueue for QoS in the router application (see #5950)
cf3eef5 Implement QueueGetConfigRequest (see #5950)
2844e19 Checks northbound applications' dependencies among them (see #6001)
d2613f6 Minor typo changes
eafc9b1 Remove useless comments
299f581 Remove OnFlowRemoved callback handler from northbound applications
4863b61 Change OF action's output type from map to slice
dbab7c4 Drop an incoming packet heading to a private address
e49fb98 Add SIGHUP handler to northbound applications and extra debugging messages
2bf9592 Drop an incoming packet heading to link-local address
05db1b0 Add extra debugging messages
9c42639 Fix missing flow reverse
10df6b1 Add verbose debugging messages
ba0ed3e Implement HUP signal handler to show current daemon status (see #5974)
386fa87 Refactoring of Dockerfile and entrypoint script
240ad0a Update README.md
7858b41 Update README.md
1ac3427 Update README.md
e708323 Update README.md
a389236 Update README.md
eaf16e0 Update README.md
5412891 Remove MySQL from Dockerfile
8b733aa Remove SIGHUP from the Docker entrypoint script
d536fa5 Update README.md
3eb59ea Update README.md
8c5308c Update README.md
7473a51 Update README.md
3d25588 Update README.md
3e94b80 Add Dockerfile
cbdbe46 Remove internal prefixes of import paths
da3f8c1 Implement ICMP echo reply
9225b3c Update README.md
062645b Change MAC address type of the database schema
529b1aa Separate database module
65aea0a Preventing IP spoofing
9e9d0a7 Preventing IP spoofing
* v0.8.0 (Thu Jul 2 23:43:09 2015 +0900)
d42c3d5 Router's outgoing packet handler (see #5084)
548de57 Router's incoming packet handler (see #5084)
593060b Update README.md
d730618 Update README.md
d19a1fc Update copyright
b4ccf88 Update copyright
43eaee1 Update README.md
3cc461f Implement custom log writer that supports log level filter
9ce0b7f Update README.md
5321096 Update README.md
c281b64 Update README.md
1cbdc63 Move the LICENSE file
7af5145 Create README.md
24d6324 Default config to use only L2Switch
6568a71 Replace git.sds.co.kr with github.com
f6550bd Add GPLv2 License
bd771ee Fix duplicated packet problem
a85ec70 Implement ProxyARP application (see #5084)
ae8751c Minor refactoring
9e4d7a4 Implement network event listener (see #5084)
e7be8db Getting OpenFlow factory from a device and cleanup flows when a device is disconnected (see #5084)
6369c0d Refactoring of the L2 switch application (see #5634)
ccf4648 Implement north-bound L2 switch applicaion (#5634)
797986b Implement north-bound application layout (see #5634)
8039ed5 Implement path finding (see #5634)
2d9ac36 Implement LLDP timer (see #5634)
96638bd Remove debugging messages
920a429 Refactoring package structure (see #5634)
ff0c33a Remove comment out for testing
7b30eb0 Refactoring auxiliary connections (see #5634)
c004856 Refactoring network packages (see #5634)
c97a99b Refactoring of the controller package (see #5634)
f6624bf Change the number of goroutines that can be executed simultaneously
4d9434b Refactoring of the OpenFlow package (see #5634)
c63ed26 Fix host DB consistency (see #5510)
6a55b26 Implement ARP announcement (see #5084)
3b8c0d5 Implement event listener (see #5084)
b8e7c93 Implement event listener (see #5084)
4963470 Remove L3 switch application (see #5084)
2c32400 Implement ProxyARP (see #5084)
b71e288 Change package name of device to controller
079cda9 Minor refactoring
89af5b1 Use both hardware and software flow tables of HP-2920G (see #5084)
46c62ea Minor refactoring
008630c Split L2 and L3 switches (see #5084)
31ccf27 Implement configuration of plugin applications (see #5084)
0490fba Implement UDP protocol (see #5454)
b2cdd8a Implement TCP protocol (see #5454)
bf85523 Fix incorrect netmask on the flow rule of L2 MAC learning switch (see #5453)
e67d097 Improve switch compatibilities (see #5453)
bf8ebff Minor refactoring of VirtualRouter
82f9db8 Add ethernet parsing routine for a IEEE 802.1Q-tagged frame (see #5454)
f8dbd02 Implment ICMP Echo protocol (see #5454)
4ccac40 Implement IPv4 protocol (see #5454)
2229248 Implement ARP protocol (see #5454)
8675846 Implement L2 switch application on OF1.0 (see #5388)
0dfcdf0 Fix abnormal broadcast when src and dst nodes are on a same switch (see #5448)
8b26a71 Fix duplicated packet problem (see #5447)
40e16f9 Implement custom routines for HP-2920 (see #5388)
0df3f20 Implement a packet processor (see #5388)
19e5e85 Implement a L2 MAC learning switch module (see #5388)
90b40da Fix port modification bugs (see #5086)
0b85e51 Fix abnormal broadcast storm (see #5086)
ee7c554 Implement L2 switch application on OF1.3 (see #5388)
2c20909 Minor refactoring (see #5086)
3933699 Remove comments
b8aa530 Implement Kruskal's algorithm (see #5086)
525f8c2 Implement Breadth-First Search (see #5086)
1b801b6 Minor refactoring
371a960 Minor fix for removing edge and vertex (see #5086)
82a6fc3 Implement minimum spanning tree using Prim's algorithm (see #5086)
dbabb82 Implement Ethernet & LLDP protocols (see #5086)
70988f7 Rollback to do not remove all flow entries when a switch connects (see #5083)
28dbc7c Fix incorrect data offset of PACKET_IN (see #5083)
46b3142 Implement port modification (see #5083)
4556131 Implement PACKET_IN (see #5083)
6700855 Add comments about switch characteristics (see #0)
68fb0e3 Implement flow_removed and packet_out message (see #5083)
a97c74e Implement flow_removed and packet_out message (see #5083)
beedd9f Add interfaces to install a flow rule (see #5083)
beb0090 Implement flow_mod (see #5083)
959f590 Implement flow action (see #5083)
c17b009 Refactoring of openflow.Message (see #5083)
6007efb Implement flow match (see #5083)
33c3ba0 Implement port status message (see #5083)
f2332d8 Add packet length validation for FeaturesReply (see #0)
76ea7fe Refactoring of error message (see #5083)
c027ba4 Implement error message (see #5083)
d05648f Implement port description (see #5083)
7144add minor refactoring (see #0)
954fbbf minor refactoring (see #0)
2172a5a Implement switch descriptions (see #5083)
fcd4c87 Implement switch configuration messages (see #5083)
0660110 Implement device pool (see #5083)
d2f8346 Split common routines OF10 and OF13 transceivers (see #5083)
6a15233 Implement a baseline for OF10 and OF13 protocols (see #5083)
c99c940 Minor refactoring (see #0)
b135795 Minor refactoring (see #0)
4234069 Refactoring for auxiliary connections (see #5083)
0c7c0ff Use map for switch ports information instead of slice (see #0)
32a3684 Minor refactoring (see #0)
d781a30 Refactoring hello phase (see #0)
7a587d4 Implement port modification message (see #5087)
c0fad5e Add atomic increment of transaction ID for concurrent usage (see #0)
6569ffd Implement barrier request and reply (see #5082)
5b5d356 Implement switch configs (see #0)
7699d4c Refactoring of FlowMatch (see #0)
cad74ff Refactoring of handleMessage() (see #0)
7c19e07 Implement all 12-tuples of flow_match (see #0)
28c918f Fix incorrect flow_match due to lack of ether_type (see #0)
3fd30d4 Implement flow_stats request and reply (see #0)
c259128 Fix the connection bug between us and a switch (see #0)
3a850d9 Refactoring of FlowMatch marshaler (see #0)
9b3ce8c Fix incorrect IP representation in a flow match structure (see #0)
14a0b1b Implement packet-out message (see #0)
14664cd Implement packet-in and flow-removed messages (see #0)
a34a56e Implement adding/removing flow rules (see #0)
6e3ccbe Fix incorrect flow action's marshal routines (see #0)
7d5cb40 Implement flow actions (see #0)
d3d43ce Implement port status message (see #0)
8dc17da Implement echo request and reply messages (see #0)
9a2d6b0 Refactoring, and implement feature capabilities and actions (see #0)
52d690c Implement HelloMessage, ErrorMessage, FeaturesRequestMessage and FeaturesReplyMessage (see #0)
f9d2ae9 Initial commit (see #0)
================================================
FILE: Dockerfile
================================================
# Start from a Debian image with the latest version of Go installed
# and a workspace (GOPATH) configured at /go.
FROM golang:1.8
MAINTAINER Kitae Kim
# Copy the local package files to the container's workspace.
ADD . /go/src/github.com/superkkt/cherry/
COPY ./cherry.yaml /usr/local/etc/
# Build cherry inside the container.
RUN go install github.com/superkkt/cherry
# Run the cherry command by default when the container starts.
ENTRYPOINT ["/go/bin/cherry"]
# Document that the service listens on port 6633.
EXPOSE 6633
================================================
FILE: Godeps/Godeps.json
================================================
{
"ImportPath": "github.com/superkkt/cherry",
"GoVersion": "go1.10",
"GodepVersion": "v79",
"Packages": [
"./..."
],
"Deps": [
{
"ImportPath": "github.com/ant0ine/go-json-rest/rest",
"Comment": "v3.3.1-8-g3a807d6",
"Rev": "3a807d6d8d36e0f9175d6c292030fce09bcbb2db"
},
{
"ImportPath": "github.com/ant0ine/go-json-rest/rest/trie",
"Comment": "v3.3.1-8-g3a807d6",
"Rev": "3a807d6d8d36e0f9175d6c292030fce09bcbb2db"
},
{
"ImportPath": "github.com/fsnotify/fsnotify",
"Comment": "v1.3.0",
"Rev": "30411dbcefb7a1da7e84f75530ad3abe4011b4f8"
},
{
"ImportPath": "github.com/go-sql-driver/mysql",
"Comment": "v1.3-59-g1a676ac",
"Rev": "1a676ac6e4dce68e9303a1800773861350374a9e"
},
{
"ImportPath": "github.com/hashicorp/golang-lru",
"Rev": "0a025b7e63adc15a622f29b0b2c4c3848243bbf6"
},
{
"ImportPath": "github.com/hashicorp/golang-lru/simplelru",
"Rev": "0a025b7e63adc15a622f29b0b2c4c3848243bbf6"
},
{
"ImportPath": "github.com/hashicorp/hcl",
"Rev": "d7400db7143f8e869812e50a53acd6c8d92af3b8"
},
{
"ImportPath": "github.com/hashicorp/hcl/hcl/ast",
"Rev": "d7400db7143f8e869812e50a53acd6c8d92af3b8"
},
{
"ImportPath": "github.com/hashicorp/hcl/hcl/parser",
"Rev": "d7400db7143f8e869812e50a53acd6c8d92af3b8"
},
{
"ImportPath": "github.com/hashicorp/hcl/hcl/scanner",
"Rev": "d7400db7143f8e869812e50a53acd6c8d92af3b8"
},
{
"ImportPath": "github.com/hashicorp/hcl/hcl/strconv",
"Rev": "d7400db7143f8e869812e50a53acd6c8d92af3b8"
},
{
"ImportPath": "github.com/hashicorp/hcl/hcl/token",
"Rev": "d7400db7143f8e869812e50a53acd6c8d92af3b8"
},
{
"ImportPath": "github.com/hashicorp/hcl/json/parser",
"Rev": "d7400db7143f8e869812e50a53acd6c8d92af3b8"
},
{
"ImportPath": "github.com/hashicorp/hcl/json/scanner",
"Rev": "d7400db7143f8e869812e50a53acd6c8d92af3b8"
},
{
"ImportPath": "github.com/hashicorp/hcl/json/token",
"Rev": "d7400db7143f8e869812e50a53acd6c8d92af3b8"
},
{
"ImportPath": "github.com/magiconair/properties",
"Comment": "v1.7.0",
"Rev": "c265cfa48dda6474e208715ca93e987829f572f8"
},
{
"ImportPath": "github.com/mitchellh/mapstructure",
"Rev": "d2dd0262208475919e1a362f675cfc0e7c10e905"
},
{
"ImportPath": "github.com/pelletier/go-buffruneio",
"Rev": "df1e16fde7fc330a0ca68167c23bf7ed6ac31d6d"
},
{
"ImportPath": "github.com/pelletier/go-toml",
"Comment": "v0.3.5-19-g7cb9880",
"Rev": "7cb988051d5045890cb91402a0b5fddc76c627bc"
},
{
"ImportPath": "github.com/pkg/errors",
"Comment": "v0.7.1",
"Rev": "17b591df37844cde689f4d5813e5cea0927d8dd2"
},
{
"ImportPath": "github.com/spf13/afero",
"Rev": "06b7e5f50606ecd49148a01a6008942d9b669217"
},
{
"ImportPath": "github.com/spf13/afero/mem",
"Rev": "06b7e5f50606ecd49148a01a6008942d9b669217"
},
{
"ImportPath": "github.com/spf13/cast",
"Rev": "27b586b42e29bec072fe7379259cc719e1289da6"
},
{
"ImportPath": "github.com/spf13/jwalterweatherman",
"Rev": "33c24e77fb80341fe7130ee7c594256ff08ccc46"
},
{
"ImportPath": "github.com/spf13/pflag",
"Rev": "cb88ea77998c3f024757528e3305022ab50b43be"
},
{
"ImportPath": "github.com/superkkt/go-logging",
"Comment": "v1-8-gd6a8aba",
"Rev": "d6a8aba149c56e15219853fff6500375e1cbb1f2"
},
{
"ImportPath": "github.com/superkkt/viper",
"Rev": "7a4f83d485c248540ad95ae0501252323b8b8682"
},
{
"ImportPath": "golang.org/x/sys/unix",
"Rev": "076b546753157f758b316e59bcb51e6807c04057"
},
{
"ImportPath": "golang.org/x/text/transform",
"Rev": "4440cd4f4c2ea31e1872e00de675a86d0c19006c"
},
{
"ImportPath": "golang.org/x/text/unicode/norm",
"Rev": "4440cd4f4c2ea31e1872e00de675a86d0c19006c"
},
{
"ImportPath": "gopkg.in/yaml.v2",
"Rev": "a83829b6f1293c91addabc89d0571c246397bbf4"
}
]
}
================================================
FILE: Godeps/Readme
================================================
This directory tree is generated automatically by godep.
Please do not edit.
See https://github.com/tools/godep for more information.
================================================
FILE: Gopkg.toml
================================================
# Gopkg.toml example
#
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
#
# [prune]
# non-go = false
# go-tests = true
# unused-packages = true
[[constraint]]
name = "github.com/davecgh/go-spew"
version = "1.1.1"
[[constraint]]
name = "github.com/fsnotify/fsnotify"
version = "1.3.0"
[[constraint]]
name = "github.com/pkg/errors"
version = "0.7.1"
[[constraint]]
branch = "master"
name = "github.com/superkkt/go-logging"
[[constraint]]
branch = "master"
name = "github.com/superkkt/viper"
[prune]
go-tests = true
unused-packages = true
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) 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
this service 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 make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. 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.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
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
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the 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 a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE 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.
END OF TERMS AND CONDITIONS
================================================
FILE: README.md
================================================
# Cherry
Cherry is an OpenFlow controller written in Go that supports OpenFlow 1.0 and 1.3 protocols. This project is not designed for general purpose, and it instead focuses on SDN (Software-Defined Networking) for an IT service provider.
## Features
* Supports OpenFlow 1.0 and 1.3 protocols
* Focuses on compatibility with commercial OpenFlow-enabled switches
* Supports network topology that has loops in it
* Provides several northbound applications: ProxyARP, L2Switch, Floating-IP, etc.
* Provides simple plugin system for northbound applications
* RESTful API to manage the controller itself
## Supported OpenFlow Switches (Fully Tested)
* Dell Force10 S4810
* Dell Force10 S3048-ON
* Dell Force10 S3148
* Open vSwitch
## Tested OpenFlow Switches
* HP 2920G
* Pica8 P-3295
* Quanta T1048-LB9
## Requirements
* MySQL (or MariaDB) database server
## Quick Start
You can install Cherry on Docker or natively from source based on your preference.
### Installing on Docker
* Install Docker if you don't have it on your system by following instruction: https://docs.docker.com/installation/
* Clone Cherry:
```$ git clone https://github.com/superkkt/cherry.git```
* Copy the template configuration:
```$ sudo cp cherry/cherry.yaml /usr/local/etc```
* Edit the configuration file */usr/local/etc/cherry.yaml* as you want.
* Build Docker image as root:
```# cd cherry; docker build -t cherry .```
* Run as root:
```# docker run -d -p 6633:6633 -v /dev/log:/dev/log -v /your/config/cherry.yaml:/usr/local/etc/cherry.yaml cherry```
The bind mount of /dev/log is to collect syslog messages from the container and then write to the host's syslog daemon.
* That's it! Cherry will be started in L2 switch mode.
### Installing from source
* Install Go language if you don't have it on your system by following instruction: http://golang.org/doc/install
* Clone and compile Cherry:
```$ go get github.com/superkkt/cherry```
* Copy the compiled binary and template configuration:
```$ sudo cp $GOPATH/bin/cherry /usr/local/bin```
```$ sudo cp $GOPATH/src/github.com/superkkt/cherry/cherry.yaml /usr/local/etc```
* Edit the configuration file */usr/local/etc/cherry.yaml* as you want.
* Run:
```$ /usr/local/bin/cherry &```
* That's it! Cherry will be started in L2 switch mode.
## Copyright and License
```
Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.
Kitae Kim <superkkt@sds.co.kr>
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 2 of the License, or
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.
```
================================================
FILE: api/core/api.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package core
import (
"encoding/json"
"fmt"
"net"
"github.com/superkkt/cherry/api"
"github.com/ant0ine/go-json-rest/rest"
"github.com/davecgh/go-spew/spew"
"github.com/superkkt/go-logging"
)
var (
logger = logging.MustGetLogger("core")
)
type API struct {
api.Server
}
func (r *API) Serve() error {
return r.Server.Serve(
rest.Post("/api/v1/status", api.ResponseHandler(r.status)),
rest.Post("/api/v1/remove", api.ResponseHandler(r.remove)),
rest.Post("/api/v1/announce", api.ResponseHandler(r.announce)),
)
}
func (r *API) status(w api.ResponseWriter, req *rest.Request) {
logger.Debugf("status request from %v", req.RemoteAddr)
w.Write(api.Response{
Status: api.StatusOkay,
Data: struct {
Master bool `json:"master"`
}{
Master: r.Observer.IsMaster(),
},
})
}
func (r *API) remove(w api.ResponseWriter, req *rest.Request) {
p := new(removeParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("remove request from %v: %v", req.RemoteAddr, spew.Sdump(p))
if p.MAC == nil {
if err := r.Controller.RemoveFlows(); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to remove flows: %v", err.Error())})
return
}
} else {
if err := r.Controller.RemoveFlowsByMAC(p.MAC); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to remove flows by MAC: %v", err.Error())})
return
}
}
w.Write(api.Response{Status: api.StatusOkay})
}
type removeParam struct {
MAC net.HardwareAddr
}
func (r *removeParam) UnmarshalJSON(data []byte) error {
v := struct {
MAC string `json:"mac"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
// If MAC is empty, remove all flows.
if len(v.MAC) == 0 {
return nil
}
addr, err := net.ParseMAC(v.MAC)
if err != nil {
return err
}
r.MAC = addr
return nil
}
func (r *API) announce(w api.ResponseWriter, req *rest.Request) {
p := new(announceParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("announce request from %v: %v", req.RemoteAddr, spew.Sdump(p))
if err := r.Controller.Announce(p.IP, p.MAC); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to announce a new ARP entry: %v", err.Error())})
return
}
w.Write(api.Response{Status: api.StatusOkay})
}
type announceParam struct {
IP net.IP
MAC net.HardwareAddr
}
func (r *announceParam) UnmarshalJSON(data []byte) error {
v := struct {
IP string `json:"ip"`
MAC string `json:"mac"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
ip := net.ParseIP(v.IP)
if ip == nil {
return fmt.Errorf("invalid IP address: %v", v.IP)
}
mac, err := net.ParseMAC(v.MAC)
if err != nil {
return err
}
r.IP = ip
r.MAC = mac
return nil
}
================================================
FILE: api/response.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package api
import (
"net/http"
"github.com/ant0ine/go-json-rest/rest"
"github.com/davecgh/go-spew/spew"
)
/*
* Status Codes:
*
* 200 = Okay.
* 4xx = Client-side errors.
* 5xx = Server-side errors.
*/
type Status int
const (
StatusOkay = 200
StatusInvalidParameter = 400
StatusIncorrectCredential = 401
StatusUnknownSession = 402
StatusPermissionDenied = 403
StatusDuplicated = 404
StatusNotFound = 405
StatusBlockedAccount = 406
StatusBlockedHost = 407
StatusInternalServerError = 500
StatusServiceUnavailable = 501
)
type Response struct {
Status Status `json:"status"`
Message string `json:"message,omitempty"` // Human readable message related with the status code.
Data interface{} `json:"data,omitempty"`
}
func ResponseHandler(f func(ResponseWriter, *rest.Request)) func(rest.ResponseWriter, *rest.Request) {
return func(w rest.ResponseWriter, req *rest.Request) {
lw := &logWriter{w: w}
f(lw, req)
}
}
type ResponseWriter interface {
// Identical to the http.ResponseWriter interface
Header() http.Header
Write(Response)
// Similar to the http.ResponseWriter interface, with additional JSON related
// headers set.
WriteHeader(int)
}
type logWriter struct {
w rest.ResponseWriter
}
func (r *logWriter) Header() http.Header {
return r.w.Header()
}
func (r *logWriter) Write(resp Response) {
switch {
case resp.Status >= StatusInternalServerError:
logger.Errorf("server-side error response: status=%v, message=%v", resp.Status, resp.Message)
case resp.Status >= StatusInvalidParameter:
logger.Infof("client-side error response: status=%v, message=%v", resp.Status, resp.Message)
default:
logger.Debugf("success response: %v", spew.Sdump(resp))
}
if err := r.w.WriteJson(resp); err != nil {
logger.Errorf("failed to write a JSON response: %v", err)
}
}
func (r *logWriter) WriteHeader(status int) {
r.w.WriteHeader(status)
}
================================================
FILE: api/server.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package api
import (
"errors"
"fmt"
"net"
"net/http"
"github.com/ant0ine/go-json-rest/rest"
"github.com/superkkt/go-logging"
)
var (
logger = logging.MustGetLogger("api")
)
type Server struct {
Port uint16
TLS struct {
Cert string // Path for a TLS certification file.
Key string // Path for a TLS private key file.
}
Observer Observer
Controller Controller
}
type Observer interface {
IsMaster() bool
}
type Controller interface {
Announce(net.IP, net.HardwareAddr) error
RemoveFlows() error
RemoveFlowsByMAC(net.HardwareAddr) error
}
func (r *Server) validate() error {
if r.Observer == nil {
return errors.New("nil observer")
}
if r.Controller == nil {
return errors.New("nil controller")
}
return nil
}
func (r *Server) Serve(routes ...*rest.Route) error {
if err := r.validate(); err != nil {
return err
}
api := rest.NewApi()
// Middleware to set the CORS header.
api.Use(rest.MiddlewareSimple(func(handler rest.HandlerFunc) rest.HandlerFunc {
return func(writer rest.ResponseWriter, request *rest.Request) {
writer.Header().Set("Access-Control-Allow-Origin", "*")
handler(writer, request)
}
}))
// Middleware to deny the client requests if we are not the master controller.
api.Use(rest.MiddlewareSimple(func(handler rest.HandlerFunc) rest.HandlerFunc {
return func(writer rest.ResponseWriter, request *rest.Request) {
if r.Observer.IsMaster() == false {
writer.WriteJson(Response{Status: StatusServiceUnavailable, Message: "use the master controller server"})
return
}
handler(writer, request)
}
}))
router, err := rest.MakeRouter(routes...)
if err != nil {
return err
}
api.SetApp(router)
// Listen on all interfaces.
addr := fmt.Sprintf(":%v", r.Port)
if r.TLS.Cert != "" && r.TLS.Key != "" {
err = http.ListenAndServeTLS(addr, r.TLS.Cert, r.TLS.Key, api.MakeHandler())
} else {
err = http.ListenAndServe(addr, api.MakeHandler())
}
return err
}
================================================
FILE: api/ui/api.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package ui
import (
"errors"
"fmt"
"net"
"strconv"
"strings"
"time"
"github.com/superkkt/cherry/api"
"github.com/ant0ine/go-json-rest/rest"
"github.com/superkkt/go-logging"
)
var (
logger = logging.MustGetLogger("ui")
)
type API struct {
api.Server
DB Database
LDAP LDAP
session *session
}
type Database interface {
// Exec executes all queries of f in a single transaction. f should return the error raised from the Transaction
// without any change or wrapping it for deadlock protection.
Exec(f func(Transaction) error) error
}
type LDAP interface {
Auth(username, password string) (ok bool, err error)
}
type Transaction interface {
UserTransaction
GroupTransaction
SwitchTransaction
NetworkTransaction
IPTransaction
HostTransaction
VIPTransaction
LogTransaction
CategoryTransaction
ComponentTransaction
}
type Search struct {
Key Column `json:"key"`
Value string `json:"value"`
}
func (r *Search) Validate() error {
switch r.Key {
case ColumnIP:
return validateIP(r.Value)
case ColumnMAC:
return validateMAC(r.Value)
case ColumnLogType:
return LogType(r.Value).Validate()
case ColumnLogMethod:
return LogMethod(r.Value).Validate()
case ColumnPort, ColumnGroup, ColumnDescription, ColumnUser:
if len(r.Value) == 0 {
return errors.New("empty search value")
}
return nil
default:
return fmt.Errorf("invalid search key: %v", r.Key)
}
}
// IP format is '1.*.*.*', '1.2.*.*', '1.2.3.*', '1.2.3.4'.
func validateIP(ip string) error {
invalid := fmt.Errorf("invalid IP address: %v", ip)
token := strings.Split(ip, ".")
if len(token) != 4 {
return invalid
}
var wildcard [4]bool
for i, v := range token {
if v == "*" {
wildcard[i] = true
continue
}
d, err := strconv.Atoi(v)
if err != nil || (d < 0 || d > 255) {
return invalid
}
}
if wildcard[0] == true {
return invalid
}
if wildcard[1] == true && (wildcard[2] == false || wildcard[3] == false) {
return invalid
}
if wildcard[2] == true && wildcard[3] == false {
return invalid
}
return nil
}
// MAC format is 'A1:*:*:*:*:*', 'A1:A2:*:*:*:*', 'A1:A2:A3:*:*:*', 'A1:A2:A3:A4:*:*', 'A1:A2:A3:A4:A5:*', 'A1:A2:A3:A4:A5:A6'.
func validateMAC(mac string) error {
invalid := fmt.Errorf("invalid MAC address: %v", mac)
token := strings.Split(mac, ":")
if len(token) != 6 {
return invalid
}
var wildcard [6]bool
for i, v := range token {
if v == "*" {
wildcard[i] = true
continue
}
d, err := strconv.ParseUint(v, 16, 8)
if len(v) != 2 || err != nil || (d < 0 || d > 255) {
return invalid
}
}
if wildcard[0] == true {
return invalid
}
if wildcard[1] == true && (wildcard[2] == false || wildcard[3] == false || wildcard[4] == false || wildcard[5] == false) {
return invalid
}
if wildcard[2] == true && (wildcard[3] == false || wildcard[4] == false || wildcard[5] == false) {
return invalid
}
if wildcard[3] == true && (wildcard[4] == false || wildcard[5] == false) {
return invalid
}
if wildcard[4] == true && wildcard[5] == false {
return invalid
}
return nil
}
type Sort struct {
Key Column `json:"key"`
Order Order `json:"order"`
}
func (r *Sort) Validate() error {
if r.Order <= OrderInvalid || r.Order > OrderDescending {
return errors.New("invalid sort order")
}
if r.Key <= ColumnInvalid || r.Key > ColumnGroup {
return fmt.Errorf("invalid sort key: %v", r.Key)
}
return nil
}
type Column int
const (
ColumnInvalid Column = iota
ColumnTime
ColumnIP
ColumnMAC
ColumnPort
ColumnGroup
ColumnDescription
ColumnUser
ColumnLogType
ColumnLogMethod
)
type Order int
const (
OrderInvalid Order = iota
OrderAscending
OrderDescending
)
type Pagination struct {
Offset uint32 `json:"offset"`
Limit uint8 `json:"limit"`
}
func (r *API) Serve() error {
if r.DB == nil {
return errors.New("nil DB")
}
r.session = newSession(256, 2*time.Hour)
return r.Server.Serve(
rest.Post("/api/v1/user/login", api.ResponseHandler(r.login)),
rest.Post("/api/v1/user/logout", api.ResponseHandler(r.logout)),
rest.Post("/api/v1/user/list", api.ResponseHandler(r.listUser)),
rest.Post("/api/v1/user/add", api.ResponseHandler(r.addUser)),
rest.Post("/api/v1/user/update", api.ResponseHandler(r.updateUser)),
rest.Post("/api/v1/user/reset", api.ResponseHandler(r.resetOTP)),
rest.Post("/api/v1/group/list", api.ResponseHandler(r.listGroup)),
rest.Post("/api/v1/group/add", api.ResponseHandler(r.addGroup)),
rest.Post("/api/v1/group/update", api.ResponseHandler(r.updateGroup)),
rest.Post("/api/v1/group/remove", api.ResponseHandler(r.removeGroup)),
rest.Post("/api/v1/switch/list", api.ResponseHandler(r.listSwitch)),
rest.Post("/api/v1/switch/add", api.ResponseHandler(r.addSwitch)),
rest.Post("/api/v1/switch/remove", api.ResponseHandler(r.removeSwitch)),
rest.Post("/api/v1/network/list", api.ResponseHandler(r.listNetwork)),
rest.Post("/api/v1/network/add", api.ResponseHandler(r.addNetwork)),
rest.Post("/api/v1/network/remove", api.ResponseHandler(r.removeNetwork)),
rest.Post("/api/v1/network/ip", api.ResponseHandler(r.listIP)),
rest.Post("/api/v1/host/list", api.ResponseHandler(r.listHost)),
rest.Post("/api/v1/host/get", api.ResponseHandler(r.getHost)),
rest.Post("/api/v1/host/add", api.ResponseHandler(r.addHost)),
rest.Post("/api/v1/host/update", api.ResponseHandler(r.updateHost)),
rest.Post("/api/v1/host/activate", api.ResponseHandler(r.activateHost)),
rest.Post("/api/v1/host/deactivate", api.ResponseHandler(r.deactivateHost)),
rest.Post("/api/v1/host/remove", api.ResponseHandler(r.removeHost)),
rest.Post("/api/v1/vip/list", api.ResponseHandler(r.listVIP)),
rest.Post("/api/v1/vip/add", api.ResponseHandler(r.addVIP)),
rest.Post("/api/v1/vip/remove", api.ResponseHandler(r.removeVIP)),
rest.Post("/api/v1/vip/toggle", api.ResponseHandler(r.toggleVIP)),
rest.Post("/api/v1/log/list", api.ResponseHandler(r.listLog)),
rest.Post("/api/v1/category/list", api.ResponseHandler(r.listCategory)),
rest.Post("/api/v1/category/add", api.ResponseHandler(r.addCategory)),
rest.Post("/api/v1/category/update", api.ResponseHandler(r.updateCategory)),
rest.Post("/api/v1/category/remove", api.ResponseHandler(r.removeCategory)),
rest.Post("/api/v1/component/list", api.ResponseHandler(r.listComponent)),
rest.Post("/api/v1/component/add", api.ResponseHandler(r.addComponent)),
rest.Post("/api/v1/component/update", api.ResponseHandler(r.updateComponent)),
rest.Post("/api/v1/component/remove", api.ResponseHandler(r.removeComponent)),
)
}
func (r *API) announce(cidr, mac string) error {
i, _, err := net.ParseCIDR(cidr)
if err != nil {
return err
}
m, err := net.ParseMAC(mac)
if err != nil {
return err
}
logger.Debugf("sending ARP announcement to all hosts to update their ARP caches: ip=%v, mac=%v", i, m)
if err := r.Controller.Announce(i, m); err != nil {
// Ignore this error.
logger.Errorf("failed to send ARP announcement: %v", err)
} else {
logger.Debugf("updated all hosts ARP caches: ip=%v, mac=%v", i, m)
}
return nil
}
================================================
FILE: api/ui/category.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package ui
import (
"encoding/json"
"errors"
"fmt"
"time"
"unicode/utf8"
"github.com/superkkt/cherry/api"
"github.com/ant0ine/go-json-rest/rest"
"github.com/davecgh/go-spew/spew"
)
type CategoryTransaction interface {
// Categories returns a list of registered categories. Pagination limit can be 0 that means no pagination.
Categories(Pagination) ([]*Category, error)
AddCategory(requesterID uint64, name string) (category *Category, duplicated bool, err error)
// UpdateCategory updates name of a category specified by id and then returns information of the category. It returns nil if the category does not exist.
UpdateCategory(requesterID, categoryID uint64, name string) (category *Category, duplicated bool, err error)
// RemoveCategory removes a category specified by id and then returns information of the category before removing. It returns nil if the category does not exist.
RemoveCategory(requesterID, categoryID uint64) (*Category, error)
}
type Category struct {
ID uint64
Name string
Timestamp time.Time
}
func (r *Category) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
ID uint64 `json:"id"`
Name string `json:"name"`
Timestamp int64 `json:"timestamp"`
}{
ID: r.ID,
Name: r.Name,
Timestamp: r.Timestamp.Unix(),
})
}
func (r *API) listCategory(w api.ResponseWriter, req *rest.Request) {
p := new(listCategoryParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode params: %v", err.Error())})
return
}
logger.Debugf("listCategory request from %v: %v", req.RemoteAddr, spew.Sdump(p))
if _, ok := r.session.Get(p.SessionID); ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var category []*Category
f := func(tx Transaction) (err error) {
category, err = tx.Categories(p.Pagination)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to query the category list: %v", err.Error())})
return
}
logger.Debugf("queried category list: %v", spew.Sdump(category))
w.Write(api.Response{Status: api.StatusOkay, Data: category})
}
type listCategoryParam struct {
SessionID string
Pagination Pagination
}
func (r *listCategoryParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
Pagination Pagination `json:"pagination"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = listCategoryParam(v)
return r.validate()
}
func (r *listCategoryParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
return nil
}
func (r *API) addCategory(w api.ResponseWriter, req *rest.Request) {
p := new(addCategoryParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode params: %v", err.Error())})
return
}
logger.Debugf("addCategory request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var category *Category
var duplicated bool
f := func(tx Transaction) (err error) {
category, duplicated, err = tx.AddCategory(session.(*User).ID, p.Name)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to add a new category: %v", err.Error())})
return
}
if duplicated {
w.Write(api.Response{Status: api.StatusDuplicated, Message: fmt.Sprintf("duplicated category: %v", p.Name)})
return
}
logger.Debugf("added category info: %v", spew.Sdump(category))
w.Write(api.Response{Status: api.StatusOkay, Data: category})
}
type addCategoryParam struct {
SessionID string
Name string
}
func (r *addCategoryParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
Name string `json:"name"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = addCategoryParam(v)
return r.validate()
}
func (r *addCategoryParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if utf8.RuneCountInString(r.Name) < 2 || utf8.RuneCountInString(r.Name) > 255 {
return fmt.Errorf("invalid name: %v", r.Name)
}
return nil
}
func (r *API) updateCategory(w api.ResponseWriter, req *rest.Request) {
p := new(updateCategoryParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode params: %v", err.Error())})
return
}
logger.Debugf("updateCategory request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var category *Category
var duplicated bool
f := func(tx Transaction) (err error) {
category, duplicated, err = tx.UpdateCategory(session.(*User).ID, p.ID, p.Name)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to update category info: %v", err.Error())})
return
}
if duplicated {
w.Write(api.Response{Status: api.StatusDuplicated, Message: fmt.Sprintf("duplicated category: %v", p.Name)})
return
}
if category == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found category to update: %v", p.ID)})
return
}
logger.Debugf("updated category info: %v", spew.Sdump(category))
w.Write(api.Response{Status: api.StatusOkay, Data: category})
}
type updateCategoryParam struct {
SessionID string
ID uint64
Name string
}
func (r *updateCategoryParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
Name string `json:"name"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = updateCategoryParam(v)
return r.validate()
}
func (r *updateCategoryParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ID == 0 {
return errors.New("invalid category id")
}
if utf8.RuneCountInString(r.Name) < 2 || utf8.RuneCountInString(r.Name) > 255 {
return fmt.Errorf("invalid name: %v", r.Name)
}
return nil
}
func (r *API) removeCategory(w api.ResponseWriter, req *rest.Request) {
p := new(removeCategoryParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode params: %v", err.Error())})
return
}
logger.Debugf("removeCategory request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var category *Category
f := func(tx Transaction) (err error) {
category, err = tx.RemoveCategory(session.(*User).ID, p.ID)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to remove category info: %v", err.Error())})
return
}
if category == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found category to remove: %v", p.ID)})
return
}
logger.Debugf("removed category info: %v", spew.Sdump(category))
w.Write(api.Response{Status: api.StatusOkay})
}
type removeCategoryParam struct {
SessionID string
ID uint64
}
func (r *removeCategoryParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = removeCategoryParam(v)
return r.validate()
}
func (r *removeCategoryParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ID == 0 {
return errors.New("invalid category id")
}
return nil
}
================================================
FILE: api/ui/component.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package ui
import (
"encoding/json"
"errors"
"fmt"
"time"
"unicode/utf8"
"github.com/superkkt/cherry/api"
"github.com/ant0ine/go-json-rest/rest"
"github.com/davecgh/go-spew/spew"
)
type ComponentTransaction interface {
// Components returns a list of registered components. Pagination limit can be 0 that means no pagination.
Components(categoryID uint64, pagination Pagination) ([]*Component, error)
AddComponent(requesterID, categoryID uint64, name string) (component *Component, duplicated bool, err error)
// UpdateComponent updates name of a component specified by id and then returns information of the component. It returns nil if the component does not exist.
UpdateComponent(requesterID, componentID uint64, name string) (component *Component, duplicated bool, err error)
// RemoveComponent removes a component specified by id and then returns information of the component before removing. It returns nil if the component does not exist.
RemoveComponent(requesterID, componentID uint64) (*Component, error)
}
type Component struct {
ID uint64
Category Category
Name string
Timestamp time.Time
}
func (r *Component) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
ID uint64 `json:"id"`
Category Category `json:"category"`
Name string `json:"name"`
Timestamp int64 `json:"timestamp"`
}{
ID: r.ID,
Category: r.Category,
Name: r.Name,
Timestamp: r.Timestamp.Unix(),
})
}
func (r *API) listComponent(w api.ResponseWriter, req *rest.Request) {
p := new(listComponentParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode params: %v", err.Error())})
return
}
logger.Debugf("listComponent request from %v: %v", req.RemoteAddr, spew.Sdump(p))
if _, ok := r.session.Get(p.SessionID); ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var component []*Component
f := func(tx Transaction) (err error) {
component, err = tx.Components(p.CategoryID, p.Pagination)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to query the component list: %v", err.Error())})
return
}
logger.Debugf("queried component list: %v", spew.Sdump(component))
w.Write(api.Response{Status: api.StatusOkay, Data: component})
}
type listComponentParam struct {
SessionID string
CategoryID uint64
Pagination Pagination
}
func (r *listComponentParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
CategoryID uint64 `json:"category_id"`
Pagination Pagination `json:"pagination"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = listComponentParam(v)
return r.validate()
}
func (r *listComponentParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.CategoryID == 0 {
return errors.New("invalid category id")
}
return nil
}
func (r *API) addComponent(w api.ResponseWriter, req *rest.Request) {
p := new(addComponentParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode params: %v", err.Error())})
return
}
logger.Debugf("addComponent request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var component *Component
var duplicated bool
f := func(tx Transaction) (err error) {
component, duplicated, err = tx.AddComponent(session.(*User).ID, p.CategoryID, p.Name)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to add a new component: %v", err.Error())})
return
}
if duplicated {
w.Write(api.Response{Status: api.StatusDuplicated, Message: fmt.Sprintf("duplicated component: category_id=%v, name=%v", p.CategoryID, p.Name)})
return
}
logger.Debugf("added component info: %v", spew.Sdump(component))
w.Write(api.Response{Status: api.StatusOkay, Data: component})
}
type addComponentParam struct {
SessionID string
CategoryID uint64
Name string
}
func (r *addComponentParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
CategoryID uint64 `json:"category_id"`
Name string `json:"name"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = addComponentParam(v)
return r.validate()
}
func (r *addComponentParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.CategoryID == 0 {
return errors.New("invalid category id")
}
if utf8.RuneCountInString(r.Name) < 2 || utf8.RuneCountInString(r.Name) > 255 {
return fmt.Errorf("invalid name: %v", r.Name)
}
return nil
}
func (r *API) updateComponent(w api.ResponseWriter, req *rest.Request) {
p := new(updateComponentParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode params: %v", err.Error())})
return
}
logger.Debugf("updateComponent request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var component *Component
var duplicated bool
f := func(tx Transaction) (err error) {
component, duplicated, err = tx.UpdateComponent(session.(*User).ID, p.ID, p.Name)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to update component info: %v", err.Error())})
return
}
if duplicated {
w.Write(api.Response{Status: api.StatusDuplicated, Message: fmt.Sprintf("duplicated component: %v", p.Name)})
return
}
if component == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found component to update: %v", p.ID)})
return
}
logger.Debugf("updated component info: %v", spew.Sdump(component))
w.Write(api.Response{Status: api.StatusOkay, Data: component})
}
type updateComponentParam struct {
SessionID string
ID uint64
Name string
}
func (r *updateComponentParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
Name string `json:"name"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = updateComponentParam(v)
return r.validate()
}
func (r *updateComponentParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ID == 0 {
return errors.New("invalid component id")
}
if utf8.RuneCountInString(r.Name) < 2 || utf8.RuneCountInString(r.Name) > 255 {
return fmt.Errorf("invalid name: %v", r.Name)
}
return nil
}
func (r *API) removeComponent(w api.ResponseWriter, req *rest.Request) {
p := new(removeComponentParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode params: %v", err.Error())})
return
}
logger.Debugf("removeComponent request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var component *Component
f := func(tx Transaction) (err error) {
component, err = tx.RemoveComponent(session.(*User).ID, p.ID)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to remove component info: %v", err.Error())})
return
}
if component == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found component to remove: %v", p.ID)})
return
}
logger.Debugf("removed component info: %v", spew.Sdump(component))
w.Write(api.Response{Status: api.StatusOkay})
}
type removeComponentParam struct {
SessionID string
ID uint64
}
func (r *removeComponentParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = removeComponentParam(v)
return r.validate()
}
func (r *removeComponentParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ID == 0 {
return errors.New("invalid component id")
}
return nil
}
================================================
FILE: api/ui/group.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package ui
import (
"encoding/json"
"errors"
"fmt"
"time"
"unicode/utf8"
"github.com/superkkt/cherry/api"
"github.com/ant0ine/go-json-rest/rest"
"github.com/davecgh/go-spew/spew"
)
type GroupTransaction interface {
// Groups returns a list of registered groups. Pagination limit can be 0 that means no pagination.
Groups(Pagination) ([]*Group, error)
AddGroup(requesterID uint64, name string) (group *Group, duplicated bool, err error)
// UpdateGroup updates name of a group specified by id and then returns information of the group. It returns nil if the group does not exist.
UpdateGroup(requesterID, groupID uint64, name string) (group *Group, duplicated bool, err error)
// RemoveGroup removes a group specified by id and then returns information of the group before removing. It returns nil if the group does not exist.
RemoveGroup(requesterID, groupID uint64) (*Group, error)
}
type Group struct {
ID uint64 `json:"id"`
Name string `json:"name"`
Timestamp time.Time `json:"timestamp"`
}
func (r *Group) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
ID uint64 `json:"id"`
Name string `json:"name"`
Timestamp int64 `json:"timestamp"`
}{
ID: r.ID,
Name: r.Name,
Timestamp: r.Timestamp.Unix(),
})
}
func (r *API) listGroup(w api.ResponseWriter, req *rest.Request) {
p := new(listGroupParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("listGroup request from %v: %v", req.RemoteAddr, spew.Sdump(p))
if _, ok := r.session.Get(p.SessionID); ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var group []*Group
f := func(tx Transaction) (err error) {
group, err = tx.Groups(p.Pagination)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to query the groups: %v", err.Error())})
return
}
logger.Debugf("queried group list: %v", spew.Sdump(group))
w.Write(api.Response{Status: api.StatusOkay, Data: group})
}
type listGroupParam struct {
SessionID string
Pagination Pagination
}
func (r *listGroupParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
Pagination Pagination `json:"pagination"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = listGroupParam(v)
return r.validate()
}
func (r *listGroupParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
return nil
}
func (r *API) addGroup(w api.ResponseWriter, req *rest.Request) {
p := new(addGroupParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("addGroup request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var group *Group
var duplicated bool
f := func(tx Transaction) (err error) {
group, duplicated, err = tx.AddGroup(session.(*User).ID, p.Name)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to add a new group: %v", err.Error())})
return
}
if duplicated {
w.Write(api.Response{Status: api.StatusDuplicated, Message: fmt.Sprintf("duplicated group: %v", p.Name)})
return
}
logger.Debugf("added group info: %v", spew.Sdump(group))
w.Write(api.Response{Status: api.StatusOkay, Data: group})
}
type addGroupParam struct {
SessionID string
Name string
}
func (r *addGroupParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
Name string `json:"name"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = addGroupParam(v)
return r.validate()
}
func (r *addGroupParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if utf8.RuneCountInString(r.Name) < 2 || utf8.RuneCountInString(r.Name) > 25 {
return fmt.Errorf("invalid name: %v", r.Name)
}
return nil
}
func (r *API) updateGroup(w api.ResponseWriter, req *rest.Request) {
p := new(updateGroupParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("updateGroup request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var group *Group
var duplicated bool
f := func(tx Transaction) (err error) {
group, duplicated, err = tx.UpdateGroup(session.(*User).ID, p.ID, p.Name)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to update a group: %v", err.Error())})
return
}
if duplicated {
w.Write(api.Response{Status: api.StatusDuplicated, Message: fmt.Sprintf("duplicated group: %v", p.Name)})
return
}
if group == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found group to update: %v", p.ID)})
return
}
logger.Debugf("updated the group: %v", spew.Sdump(group))
w.Write(api.Response{Status: api.StatusOkay, Data: group})
}
type updateGroupParam struct {
SessionID string
ID uint64
Name string
}
func (r *updateGroupParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
Name string `json:"name"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = updateGroupParam(v)
return r.validate()
}
func (r *updateGroupParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ID == 0 {
return errors.New("invalid group id")
}
if utf8.RuneCountInString(r.Name) < 2 || utf8.RuneCountInString(r.Name) > 25 {
return fmt.Errorf("invalid name: %v", r.Name)
}
return nil
}
func (r *API) removeGroup(w api.ResponseWriter, req *rest.Request) {
p := new(removeGroupParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("removeGroup request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var group *Group
f := func(tx Transaction) (err error) {
group, err = tx.RemoveGroup(session.(*User).ID, p.ID)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to remove a group: %v", err.Error())})
return
}
if group == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found group to remove: %v", p.ID)})
return
}
logger.Debugf("removed the group: %v", spew.Sdump(group))
w.Write(api.Response{Status: api.StatusOkay})
}
type removeGroupParam struct {
SessionID string
ID uint64
}
func (r *removeGroupParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = removeGroupParam(v)
return r.validate()
}
func (r *removeGroupParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ID == 0 {
return errors.New("invalid group id")
}
return nil
}
================================================
FILE: api/ui/host.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package ui
import (
"encoding/json"
"errors"
"fmt"
"net"
"time"
"unicode/utf8"
"github.com/superkkt/cherry/api"
"github.com/superkkt/cherry/network"
"github.com/ant0ine/go-json-rest/rest"
"github.com/davecgh/go-spew/spew"
)
var (
errDuplicated = errors.New("duplicated error")
errNotFound = errors.New("not found error")
errBlocked = errors.New("blocked error")
)
type HostTransaction interface {
Host(id uint64) (*Host, error)
// Hosts returns a list of registered hosts. Search can be nil that means no search. Pagination limit can be 0 that means no pagination.
Hosts(*Search, Sort, Pagination) ([]*Host, error)
AddHost(requesterID, ipID uint64, groupID *uint64, mac net.HardwareAddr, desc string, spec []SpecParam) (host *Host, duplicated bool, err error)
// UpdateHost updates a host specified by id and then returns information of the host. The parameters used for update can be nil that means no update about the parameters.
UpdateHost(requesterID, hostID uint64, ipID, groupID *uint64, mac net.HardwareAddr, description *string, spec []SpecParam) (host *Host, duplicated bool, err error)
// ActivateHost enables a host specified by id and then returns information of the host. It returns nil if the host does not exist.
ActivateHost(requesterID, hostID uint64) (*Host, error)
// DeactivateHost disables a host specified by id and then returns information of the host. It returns nil if the host does not exist.
DeactivateHost(requesterID, hostID uint64) (*Host, error)
CountVIPByHostID(id uint64) (count uint64, err error)
// RemoveHost removes a host specified by id and then returns information of the host before removing. It returns nil if the host does not exist.
RemoveHost(requesterID, hostID uint64) (*Host, error)
}
type Host struct {
ID uint64
IP string // FIXME: Use a native type.
Port string
Group string
MAC string // FIXME: Use a native type.
Description string
Enabled bool
Stale bool
Spec []*Spec
Timestamp time.Time
}
func (r *Host) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
ID uint64 `json:"id"`
IP string `json:"ip"`
Port string `json:"port"`
Group string `json:"group"`
MAC string `json:"mac"`
Description string `json:"description"`
Enabled bool `json:"enabled"`
Stale bool `json:"stale"`
Spec []*Spec `json:"spec"`
Timestamp int64 `json:"timestamp"`
}{
ID: r.ID,
IP: r.IP,
Port: r.Port,
Group: r.Group,
MAC: r.MAC,
Description: r.Description,
Enabled: r.Enabled,
Stale: r.Stale,
Spec: r.Spec,
Timestamp: r.Timestamp.Unix(),
})
}
type Spec struct {
ID uint64 `json:"id"`
Component Component `json:"component"`
Count uint16 `json:"count"`
}
func (r *API) listHost(w api.ResponseWriter, req *rest.Request) {
p := new(listHostParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("listHost request from %v: %v", req.RemoteAddr, spew.Sdump(p))
if _, ok := r.session.Get(p.SessionID); ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var host []*Host
f := func(tx Transaction) (err error) {
host, err = tx.Hosts(p.Search, p.Sort, p.Pagination)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to query the hosts: %v", err.Error())})
return
}
logger.Debugf("queried host list: %v", spew.Sdump(host))
w.Write(api.Response{Status: api.StatusOkay, Data: host})
}
type listHostParam struct {
SessionID string
Search *Search
Sort Sort
Pagination Pagination
}
func (r *listHostParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
Search *Search `json:"search"`
Sort Sort `json:"sort"`
Pagination Pagination `json:"pagination"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = listHostParam(v)
return r.validate()
}
func (r *listHostParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
// If search is nil, fetch hosts without using search.
if r.Search != nil {
if r.Search.Key <= ColumnTime || r.Search.Key > ColumnDescription {
return errors.New("invalid search key")
}
if err := r.Search.Validate(); err != nil {
return err
}
}
if err := r.Sort.Validate(); err != nil {
return err
}
return nil
}
func (r *API) getHost(w api.ResponseWriter, req *rest.Request) {
p := new(getHostParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode params: %v", err.Error())})
return
}
logger.Debugf("getHost request from %v: %v", req.RemoteAddr, spew.Sdump(p))
if _, ok := r.session.Get(p.SessionID); ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var host *Host
f := func(tx Transaction) (err error) {
host, err = tx.Host(p.ID)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to query the host info: %v", err.Error())})
return
}
if host == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found host: %v", p.ID)})
return
}
logger.Debugf("queried host info: %v", spew.Sdump(host))
w.Write(api.Response{Status: api.StatusOkay, Data: host})
}
type getHostParam struct {
SessionID string
ID uint64
}
func (r *getHostParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = getHostParam(v)
return r.validate()
}
func (r *getHostParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ID == 0 {
return errors.New("invalid host id")
}
return nil
}
func (r *API) addHost(w api.ResponseWriter, req *rest.Request) {
p := new(addHostParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("addHost request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var host []*Host
f := func(tx Transaction) (err error) {
for _, v := range p.IPID {
h, duplicated, err := tx.AddHost(session.(*User).ID, v, p.GroupID, p.MAC, p.Description, p.Spec)
if err != nil {
return err
}
if duplicated {
return errDuplicated
}
host = append(host, h)
}
return nil
}
if err := r.DB.Exec(f); err != nil {
if err == errDuplicated {
w.Write(api.Response{Status: api.StatusDuplicated, Message: fmt.Sprintf("duplicated host: ip_id=%v", p.IPID)})
} else {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to add a new host: %v", err.Error())})
}
return
}
logger.Debugf("added host info: %v", spew.Sdump(host))
for _, v := range host {
if err := r.announce(v.IP, v.MAC); err != nil {
// Ignore this error.
logger.Errorf("failed to send ARP announcement: %v", err)
}
}
w.Write(api.Response{Status: api.StatusOkay, Data: host})
}
type addHostParam struct {
SessionID string
IPID []uint64
GroupID *uint64
MAC net.HardwareAddr
Description string
Spec []SpecParam
}
func (r *addHostParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
IPID []uint64 `json:"ip_id"`
GroupID *uint64 `json:"group_id"`
MAC string `json:"mac"`
Description string `json:"description"`
Spec []SpecParam `json:"spec"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
if len(v.SessionID) != 64 {
return errors.New("invalid session id")
}
if len(v.IPID) == 0 {
return errors.New("empty ip id")
}
if len(v.IPID) > 10 {
return errors.New("too many ip ids")
}
for _, i := range v.IPID {
if i == 0 {
return errors.New("invalid ip id")
}
}
if utf8.RuneCountInString(v.Description) > 255 {
return errors.New("too long description")
}
mac, err := net.ParseMAC(v.MAC)
if err != nil {
return err
}
for _, v := range r.Spec {
if err := v.Validate(); err != nil {
return err
}
}
r.SessionID = v.SessionID
r.IPID = v.IPID
r.GroupID = v.GroupID
r.MAC = mac
r.Description = v.Description
r.Spec = v.Spec
return nil
}
type SpecParam struct {
ComponentID uint64 `json:"component_id"`
Count uint16 `json:"count"`
}
func (r *SpecParam) Validate() error {
if r.ComponentID == 0 {
return errors.New("invalid component id")
}
if r.Count == 0 {
return errors.New("invalid count")
}
return nil
}
func (r *API) updateHost(w api.ResponseWriter, req *rest.Request) {
p := new(updateHostParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("updateHost request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var old, new *Host
f := func(tx Transaction) (err error) {
count, err := tx.CountVIPByHostID(p.ID)
if err != nil {
return err
}
if count > 0 {
return errors.New("VIP member host cannot be updated")
}
old, err = tx.Host(p.ID)
if err != nil {
return err
}
if old == nil {
return errNotFound
}
if old.Enabled == false {
return errBlocked
}
h, duplicated, err := tx.UpdateHost(session.(*User).ID, p.ID, p.IPID, p.GroupID, p.MAC, p.Description, p.Spec)
if err != nil {
return err
}
if duplicated {
return errDuplicated
}
new = h
return nil
}
if err := r.DB.Exec(f); err != nil {
switch err {
case errNotFound:
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found host to update: %v", p.ID)})
case errBlocked:
w.Write(api.Response{Status: api.StatusBlockedHost, Message: fmt.Sprintf("unable to update blocked host: %v", p.ID)})
case errDuplicated:
w.Write(api.Response{Status: api.StatusDuplicated, Message: fmt.Sprintf("duplicated host: ip_id=%v", p.IPID)})
default:
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to update a host: %v", err.Error())})
}
return
}
logger.Debugf("updated host info: %v", spew.Sdump(new))
if err := r.announce(old.IP, network.NullMAC.String()); err != nil {
// Ignore this error.
logger.Errorf("failed to send ARP announcement: %v", err)
}
if err := r.announce(new.IP, new.MAC); err != nil {
// Ignore this error.
logger.Errorf("failed to send ARP announcement: %v", err)
}
w.Write(api.Response{Status: api.StatusOkay, Data: new})
}
type updateHostParam struct {
SessionID string
ID uint64
IPID *uint64
GroupID *uint64
MAC net.HardwareAddr
Description *string
Spec []SpecParam
}
func (r *updateHostParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
IPID *uint64 `json:"ip_id"`
GroupID *uint64 `json:"group_id"`
MAC *string `json:"mac"`
Description *string `json:"description"`
Spec []SpecParam `json:"spec"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
if len(v.SessionID) != 64 {
return errors.New("invalid session id")
}
if v.ID == 0 {
return errors.New("invalid host id")
}
if v.IPID == nil && v.GroupID == nil && v.MAC == nil && v.Description == nil && v.Spec == nil {
return errors.New("not exist value to update")
}
if v.IPID != nil && *v.IPID == 0 {
return errors.New("invalid ip id")
}
if v.GroupID != nil && *v.GroupID == 0 {
return errors.New("invalid group id")
}
if v.Description != nil && utf8.RuneCountInString(*v.Description) > 255 {
return errors.New("too long description")
}
for _, v := range r.Spec {
if err := v.Validate(); err != nil {
return err
}
}
if v.MAC != nil {
v, err := net.ParseMAC(*v.MAC)
if err != nil {
return err
}
r.MAC = v
}
r.SessionID = v.SessionID
r.ID = v.ID
r.IPID = v.IPID
r.GroupID = v.GroupID
r.Description = v.Description
r.Spec = v.Spec
return nil
}
func (r *API) activateHost(w api.ResponseWriter, req *rest.Request) {
p := new(activateHostParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("activateHost request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var host *Host
f := func(tx Transaction) (err error) {
host, err = tx.ActivateHost(session.(*User).ID, p.ID)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to activate a host: %v", err.Error())})
return
}
if host == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found host to activate: %v", p.ID)})
return
}
logger.Debugf("activated host info: %v", spew.Sdump(host))
if err := r.announce(host.IP, host.MAC); err != nil {
// Ignore this error.
logger.Errorf("failed to send ARP announcement: %v", err)
}
w.Write(api.Response{Status: api.StatusOkay})
}
type activateHostParam struct {
SessionID string
ID uint64
}
func (r *activateHostParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = activateHostParam(v)
return r.validate()
}
func (r *activateHostParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ID == 0 {
return errors.New("invalid switch id")
}
return nil
}
func (r *API) deactivateHost(w api.ResponseWriter, req *rest.Request) {
p := new(deactivateHostParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("deactivateHost request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var host *Host
f := func(tx Transaction) (err error) {
count, err := tx.CountVIPByHostID(p.ID)
if err != nil {
return err
}
if count > 0 {
return errors.New("VIP member host cannot be disabled")
}
host, err = tx.DeactivateHost(session.(*User).ID, p.ID)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to deactivate a host: %v", err.Error())})
return
}
if host == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found host to deactivate: %v", p.ID)})
return
}
logger.Debugf("deactivated host info: %v", spew.Sdump(host))
if err := r.announce(host.IP, network.NullMAC.String()); err != nil {
// Ignore this error.
logger.Errorf("failed to send ARP announcement: %v", err)
}
w.Write(api.Response{Status: api.StatusOkay})
}
type deactivateHostParam struct {
SessionID string
ID uint64
}
func (r *deactivateHostParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = deactivateHostParam(v)
return r.validate()
}
func (r *deactivateHostParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ID == 0 {
return errors.New("invalid switch id")
}
return nil
}
func (r *API) removeHost(w api.ResponseWriter, req *rest.Request) {
p := new(removeHostParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("removeHost request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var host *Host
f := func(tx Transaction) (err error) {
host, err = tx.RemoveHost(session.(*User).ID, p.ID)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to remove a host: %v", err.Error())})
return
}
if host == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found host to remove: %v", p.ID)})
return
}
logger.Debugf("removed host info: %v", spew.Sdump(host))
if err := r.announce(host.IP, network.NullMAC.String()); err != nil {
// Ignore this error.
logger.Errorf("failed to send ARP announcement: %v", err)
}
w.Write(api.Response{Status: api.StatusOkay})
}
type removeHostParam struct {
SessionID string
ID uint64
}
func (r *removeHostParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = removeHostParam(v)
return r.validate()
}
func (r *removeHostParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ID == 0 {
return errors.New("invalid switch id")
}
return nil
}
================================================
FILE: api/ui/ip.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package ui
import (
"encoding/json"
"errors"
"fmt"
"github.com/superkkt/cherry/api"
"github.com/ant0ine/go-json-rest/rest"
"github.com/davecgh/go-spew/spew"
)
type IPTransaction interface {
IPAddrs(networkID uint64) ([]*IP, error)
}
type IP struct {
ID uint64 `json:"id"`
Address string `json:"address"` // FIXME: Use a native type.
Used bool `json:"used"`
Port string `json:"port"`
Host struct {
Description string `json:"description"`
Enabled bool `json:"enabled"`
Stale bool `json:"stale"`
} `json:"host"`
}
func (r *API) listIP(w api.ResponseWriter, req *rest.Request) {
p := new(listIPParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("listIP request from %v: %v", req.RemoteAddr, spew.Sdump(p))
if _, ok := r.session.Get(p.SessionID); ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var ip []*IP
f := func(tx Transaction) (err error) {
ip, err = tx.IPAddrs(p.NetworkID)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to query the network ip list: %v", err.Error())})
return
}
logger.Debugf("queried network ip list: %v", spew.Sdump(ip))
w.Write(api.Response{Status: api.StatusOkay, Data: ip})
}
type listIPParam struct {
SessionID string
NetworkID uint64
}
func (r *listIPParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
NetworkID uint64 `json:"network_id"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = listIPParam(v)
return r.validate()
}
func (r *listIPParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.NetworkID == 0 {
return errors.New("invalid network id")
}
return nil
}
================================================
FILE: api/ui/log.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package ui
import (
"encoding/json"
"errors"
"fmt"
"time"
"github.com/superkkt/cherry/api"
"github.com/ant0ine/go-json-rest/rest"
"github.com/davecgh/go-spew/spew"
)
type LogType string
const (
LogTypeUser LogType = "USER"
LogTypeGroup LogType = "GROUP"
LogTypeSwitch LogType = "SWITCH"
LogTypeNetwork LogType = "NETWORK"
LogTypeHost LogType = "HOST"
LogTypeVIP LogType = "VIP"
LogTypeCategory LogType = "CATEGORY"
LogTypeComponent LogType = "COMPONENT"
)
func (r LogType) Validate() error {
if r != LogTypeUser && r != LogTypeGroup && r != LogTypeSwitch && r != LogTypeNetwork &&
r != LogTypeHost && r != LogTypeVIP && r != LogTypeCategory && r != LogTypeComponent {
return fmt.Errorf("invalid log type: %v", r)
}
return nil
}
type LogMethod string
const (
LogMethodAdd LogMethod = "ADD"
LogMethodUpdate LogMethod = "UPDATE"
LogMethodRemove LogMethod = "REMOVE"
)
func (r LogMethod) Validate() error {
if r != LogMethodAdd && r != LogMethodUpdate && r != LogMethodRemove {
return fmt.Errorf("invalid log method: %v", r)
}
return nil
}
type LogTransaction interface {
// Logs returns a list of registered logs. Search can be nil that means no search.
QueryLog(*Search, Pagination) ([]*Log, error)
}
type Log struct {
ID uint64
User string
Type LogType
Method LogMethod
Data string
Timestamp time.Time
}
func (r *Log) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
ID uint64 `json:"id"`
User string `json:"user"`
Type string `json:"type"`
Method string `json:"method"`
Data string `json:"data"`
Timestamp int64 `json:"timestamp"`
}{
ID: r.ID,
User: r.User,
Type: string(r.Type),
Method: string(r.Method),
Data: r.Data,
Timestamp: r.Timestamp.Unix(),
})
}
func (r *API) listLog(w api.ResponseWriter, req *rest.Request) {
p := new(listLogParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("listLog request from %v: %v", req.RemoteAddr, spew.Sdump(p))
if _, ok := r.session.Get(p.SessionID); ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var log []*Log
f := func(tx Transaction) (err error) {
log, err = tx.QueryLog(p.Search, p.Pagination)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to query the log list: %v", err.Error())})
return
}
logger.Debugf("queried log list: %v", spew.Sdump(log))
w.Write(api.Response{Status: api.StatusOkay, Data: log})
}
type listLogParam struct {
SessionID string
Search *Search
Pagination Pagination
}
func (r *listLogParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
Search *Search `json:"search"`
Pagination Pagination `json:"pagination"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = listLogParam(v)
return r.validate()
}
func (r *listLogParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
// If search is nil, fetch logs without using search.
if r.Search != nil {
if r.Search.Key <= ColumnDescription || r.Search.Key > ColumnLogMethod {
return errors.New("invalid search key")
}
if err := r.Search.Validate(); err != nil {
return err
}
}
if r.Pagination.Limit == 0 {
return errors.New("invalid pagination limit")
}
return nil
}
================================================
FILE: api/ui/network.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package ui
import (
"encoding/json"
"errors"
"fmt"
"net"
"github.com/superkkt/cherry/api"
"github.com/superkkt/cherry/network"
"github.com/ant0ine/go-json-rest/rest"
"github.com/davecgh/go-spew/spew"
)
type NetworkTransaction interface {
// Networks returns a list of registered networks. Address can be nil that means no address search. Pagination limit can be 0 that means no pagination.
Networks(address *string, pagination Pagination) ([]*Network, error)
AddNetwork(requesterID uint64, addr net.IP, mask net.IPMask, gateway net.IP) (network *Network, duplicated bool, err error)
// RemoveNetwork removes a network specified by id and then returns information of the network before removing. It returns nil if the network does not exist.
RemoveNetwork(requesterID, netID uint64) (*Network, error)
}
type Network struct {
ID uint64 `json:"id"`
Address string `json:"address"` // FIXME: Use a native type.
Mask uint8 `json:"mask"` // FIXME: Use a native type.
Gateway string `json:"gateway"` // FIXME: Use a native type.
}
func (r *API) listNetwork(w api.ResponseWriter, req *rest.Request) {
p := new(listNetworkParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("listNetwork request from %v: %v", req.RemoteAddr, spew.Sdump(p))
if _, ok := r.session.Get(p.SessionID); ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var network []*Network
f := func(tx Transaction) (err error) {
network, err = tx.Networks(p.Address, p.Pagination)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to query the network list: %v", err.Error())})
return
}
logger.Debugf("queried network list: %v", spew.Sdump(network))
w.Write(api.Response{Status: api.StatusOkay, Data: network})
}
type listNetworkParam struct {
SessionID string
Address *string
Pagination Pagination
}
func (r *listNetworkParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
Address *string `json:"address"`
Pagination Pagination `json:"pagination"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = listNetworkParam(v)
return r.validate()
}
func (r *listNetworkParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.Address != nil {
if err := validateIP(*r.Address); err != nil {
return err
}
}
return nil
}
func (r *API) addNetwork(w api.ResponseWriter, req *rest.Request) {
p := new(addNetworkParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("addNetwork request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var network *Network
var duplicated bool
f := func(tx Transaction) (err error) {
network, duplicated, err = tx.AddNetwork(session.(*User).ID, p.Address, p.Mask, p.Gateway)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to add a new network: %v", err.Error())})
return
}
if duplicated {
w.Write(api.Response{Status: api.StatusDuplicated, Message: fmt.Sprintf("duplicated network: address=%v, mask=%v", p.Address, p.Mask)})
return
}
logger.Debugf("added network info: %v", spew.Sdump(network))
w.Write(api.Response{Status: api.StatusOkay, Data: network})
}
type addNetworkParam struct {
SessionID string
Address net.IP
Mask net.IPMask
Gateway net.IP
}
func (r *addNetworkParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
Address string `json:"address"`
Mask uint8 `json:"mask"`
Gateway string `json:"gateway"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
if len(v.SessionID) != 64 {
return errors.New("invalid session id")
}
if v.Mask < 24 || v.Mask > 30 {
return fmt.Errorf("invalid network mask: %v", v.Mask)
}
_, network, err := net.ParseCIDR(fmt.Sprintf("%v/%v", v.Address, v.Mask))
if err != nil || network == nil {
return fmt.Errorf("invalid network address: %v", v.Address)
}
gateway := net.ParseIP(v.Gateway)
if gateway == nil {
return fmt.Errorf("invalid network gateway: %v", v.Gateway)
}
if err := validateGateway(*network, gateway); err != nil {
return err
}
r.SessionID = v.SessionID
r.Mask = network.Mask
r.Address = network.IP
r.Gateway = gateway
return nil
}
func validateGateway(n net.IPNet, g net.IP) error {
invalid := fmt.Errorf("invalid network gateway: %v", g)
broadcast := net.IP(make([]byte, 4))
for i := range n.IP.To4() {
broadcast[i] = n.IP.To4()[i] | ^n.Mask[i]
}
reserved, err := network.ReservedIP(n)
if err != nil {
return err
}
if n.Contains(g) == false {
return invalid
}
if g.Equal(n.IP) || g.Equal(broadcast) || g.Equal(reserved) {
return invalid
}
return nil
}
func (r *API) removeNetwork(w api.ResponseWriter, req *rest.Request) {
p := new(removeNetworkParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("removeNetwork request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var network *Network
f := func(tx Transaction) (err error) {
network, err = tx.RemoveNetwork(session.(*User).ID, p.ID)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to remove a network: %v", err.Error())})
return
}
if network == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found network to remove: %v", p.ID)})
return
}
logger.Debugf("removed a network: %v", spew.Sdump(network))
logger.Debug("removing all flows from the entire switches")
if err := r.Controller.RemoveFlows(); err != nil {
// Ignore this error.
logger.Errorf("failed to remove flows: %v", err)
} else {
logger.Debug("removed all flows from the entire switches")
}
w.Write(api.Response{Status: api.StatusOkay})
}
type removeNetworkParam struct {
SessionID string
ID uint64
}
func (r *removeNetworkParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = removeNetworkParam(v)
return r.validate()
}
func (r *removeNetworkParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ID == 0 {
return errors.New("empty network id")
}
return nil
}
================================================
FILE: api/ui/session.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package ui
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"math/rand"
"strings"
"time"
"github.com/davecgh/go-spew/spew"
"github.com/hashicorp/golang-lru"
)
type session struct {
storage *lru.Cache
timeout time.Duration
}
func newSession(size int, timeout time.Duration) *session {
c, err := lru.New(size)
if err != nil {
panic(err)
}
return &session{
storage: c,
timeout: timeout,
}
}
func (r *session) Add(v interface{}) (id string) {
src := fmt.Sprintf("%v.%v.%v", spew.Sdump(v), time.Now().UnixNano(), rand.Float64())
id = strings.ToUpper(hash(src))
r.storage.Add(id, &sessionEntry{Data: v, Timestamp: time.Now()})
return id
}
type sessionEntry struct {
Data interface{}
Timestamp time.Time
}
func hash(value string) string {
h := sha256.New()
h.Write([]byte(value))
return hex.EncodeToString(h.Sum(nil))
}
func (r *session) Get(id string) (interface{}, bool) {
id = strings.ToUpper(id)
v, ok := r.storage.Get(id)
if ok == false {
return nil, false
}
e := v.(*sessionEntry)
if time.Since(e.Timestamp) > r.timeout {
r.storage.Remove(id)
return nil, false
}
e.Timestamp = time.Now()
return e.Data, true
}
func (r *session) Remove(id string) bool {
id = strings.ToUpper(id)
if r.storage.Contains(id) == false {
return false
}
r.storage.Remove(id)
return true
}
================================================
FILE: api/ui/switch.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package ui
import (
"encoding/json"
"errors"
"fmt"
"regexp"
"strconv"
"strings"
"unicode/utf8"
"github.com/superkkt/cherry/api"
"github.com/ant0ine/go-json-rest/rest"
"github.com/davecgh/go-spew/spew"
)
type SwitchTransaction interface {
Switches(Pagination) ([]*Switch, error)
AddSwitch(requesterID, dpid uint64, nPorts, firstPort, firstPrintedPort uint16, desc string) (sw *Switch, duplicated bool, err error)
// RemoveSwitch removes a switch specified by id and then returns information of the switch before removing. It returns nil if the switch does not exist.
RemoveSwitch(requesterID, swID uint64) (*Switch, error)
}
type Switch struct {
ID uint64 `json:"id"`
DPID uint64 `json:"dpid"`
NumPorts uint16 `json:"n_ports"`
FirstPort uint16 `json:"first_port"`
FirstPrintedPort uint16 `json:"first_printed_port"`
Description string `json:"description"`
}
func (r *Switch) MarshalJSON() ([]byte, error) {
s := new(struct {
ID uint64 `json:"id"`
DPID struct {
Int uint64 `json:"int"`
Hex string `json:"hex"`
} `json:"dpid"`
NumPorts uint16 `json:"n_ports"`
FirstPort uint16 `json:"first_port"`
FirstPrintedPort uint16 `json:"first_printed_port"`
Description string `json:"description"`
})
s.ID = r.ID
s.DPID.Int = r.DPID
s.DPID.Hex = hexDPID(r.DPID)
s.NumPorts = r.NumPorts
s.FirstPort = r.FirstPort
s.FirstPrintedPort = r.FirstPrintedPort
s.Description = r.Description
return json.Marshal(&s)
}
func hexDPID(dpid uint64) string {
hex := fmt.Sprintf("%016x", dpid)
re := regexp.MustCompile("..")
return strings.TrimRight(re.ReplaceAllString(hex, "$0:"), ":")
}
func (r *API) listSwitch(w api.ResponseWriter, req *rest.Request) {
p := new(listSwitchParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("listSwitch request from %v: %v", req.RemoteAddr, spew.Sdump(p))
if _, ok := r.session.Get(p.SessionID); ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var sw []*Switch
f := func(tx Transaction) (err error) {
sw, err = tx.Switches(p.Pagination)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to query the switch list: %v", err.Error())})
return
}
logger.Debugf("queried switch list: %v", spew.Sdump(sw))
w.Write(api.Response{Status: api.StatusOkay, Data: sw})
}
type listSwitchParam struct {
SessionID string
Pagination Pagination
}
func (r *listSwitchParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
Pagination Pagination `json:"pagination"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = listSwitchParam(v)
return r.validate()
}
func (r *listSwitchParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.Pagination.Limit == 0 {
return errors.New("invalid pagination limit")
}
return nil
}
func (r *API) addSwitch(w api.ResponseWriter, req *rest.Request) {
p := new(addSwitchParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("addSwitch request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var sw *Switch
var duplicated bool
f := func(tx Transaction) (err error) {
sw, duplicated, err = tx.AddSwitch(session.(*User).ID, p.DPID, p.NumPorts, p.FirstPort, p.FirstPrintedPort, p.Description)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to add a new switch: %v", err.Error())})
return
}
if duplicated {
w.Write(api.Response{Status: api.StatusDuplicated, Message: fmt.Sprintf("duplicated switch: dpid=%v", p.DPID)})
return
}
logger.Debugf("added switch info: %v", spew.Sdump(sw))
w.Write(api.Response{Status: api.StatusOkay, Data: sw})
}
type addSwitchParam struct {
SessionID string
DPID uint64
NumPorts uint16
FirstPort uint16
FirstPrintedPort uint16
Description string
}
func (r *addSwitchParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
DPID string `json:"dpid"`
NumPorts uint16 `json:"n_ports"`
FirstPort uint16 `json:"first_port"`
FirstPrintedPort uint16 `json:"first_printed_port"`
Description string `json:"description"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
if len(v.SessionID) != 64 {
return errors.New("invalid session id")
}
if v.NumPorts == 0 {
return errors.New("invalid number of ports")
}
if v.NumPorts > 512 {
return errors.New("too many ports")
}
if utf8.RuneCountInString(v.Description) > 255 {
return errors.New("too long description")
}
if uint32(v.FirstPort)+uint32(v.NumPorts) > 0xFFFF {
return errors.New("too high first port number")
}
ok, err := regexp.MatchString("^([0-9a-fA-F]{2}:){7}([0-9a-fA-F]{2})$", v.DPID)
if err != nil {
return err
}
// Is the DP id in hex format?
if ok {
v.DPID = strings.Replace(v.DPID, ":", "", -1)
if r.DPID, err = strconv.ParseUint(v.DPID, 16, 64); err != nil {
return err
}
} else {
if r.DPID, err = strconv.ParseUint(v.DPID, 10, 64); err != nil {
return err
}
}
r.SessionID = v.SessionID
r.NumPorts = v.NumPorts
r.FirstPort = v.FirstPort
r.FirstPrintedPort = v.FirstPrintedPort
r.Description = v.Description
return nil
}
func (r *API) removeSwitch(w api.ResponseWriter, req *rest.Request) {
p := new(removeSwitchParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("removeSwitch request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var sw *Switch
f := func(tx Transaction) (err error) {
sw, err = tx.RemoveSwitch(session.(*User).ID, p.ID)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to remove a switch: %v", err.Error())})
return
}
if sw == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found switch to remove: %v", p.ID)})
return
}
logger.Debugf("removed a switch: %v", spew.Sdump(sw))
logger.Debug("removing all flows from the entire switches")
if err := r.Controller.RemoveFlows(); err != nil {
// Ignore this error.
logger.Errorf("failed to remove flows: %v", err)
} else {
logger.Debug("removed all flows from the entire switches")
}
w.Write(api.Response{Status: api.StatusOkay})
}
type removeSwitchParam struct {
SessionID string
ID uint64
}
func (r *removeSwitchParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = removeSwitchParam(v)
return r.validate()
}
func (r *removeSwitchParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ID == 0 {
return errors.New("invalid switch id")
}
return nil
}
================================================
FILE: api/ui/user.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package ui
import (
"encoding/json"
"errors"
"fmt"
"time"
"github.com/superkkt/cherry/api"
"github.com/ant0ine/go-json-rest/rest"
"github.com/davecgh/go-spew/spew"
"github.com/pquerna/otp"
"github.com/pquerna/otp/totp"
)
type UserTransaction interface {
User(name string) (*User, error)
Users(Pagination) ([]*User, error)
AddUser(requesterID uint64, name, key string) (user *User, duplicated bool, err error)
// UpdateUser updates enabled and admin authorization of a user specified by id and then returns information of the user. It returns nil if the user does not exist.
UpdateUser(requesterID, userID uint64, enabled, admin *bool) (*User, error)
ResetOTPKey(name, key string) (ok bool, err error)
}
type User struct {
ID uint64
Name string
Key string // Key used in OTP Authentication.
Enabled bool
Admin bool
Timestamp time.Time
}
func (r *User) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
ID uint64 `json:"id"`
Name string `json:"name"`
Enabled bool `json:"enabled"`
Admin bool `json:"admin"`
Timestamp int64 `json:"timestamp"`
}{
ID: r.ID,
Name: r.Name,
Enabled: r.Enabled,
Admin: r.Admin,
Timestamp: r.Timestamp.Unix(),
})
}
func (r *API) login(w api.ResponseWriter, req *rest.Request) {
p := new(loginParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("login request from %v: %v", req.RemoteAddr, spew.Sdump(&struct {
Name string `json:"name"`
Code string `json:"code"`
}{
Name: p.Name,
Code: p.Code,
}))
var user *User
f := func(tx Transaction) (err error) {
user, err = tx.User(p.Name)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to query an user account: %v", err.Error())})
return
}
if user == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found user to login: %v", p.Name)})
return
}
if user.Enabled == false {
w.Write(api.Response{Status: api.StatusBlockedAccount, Message: fmt.Sprintf("login attempt with a blocked account: %v", p.Name)})
return
}
ok, err := r.LDAP.Auth(p.Name, p.Password)
if err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to authenticate an user account: %v", err.Error())})
return
}
if ok == false {
w.Write(api.Response{Status: api.StatusIncorrectCredential, Message: fmt.Sprintf("incorrect username or password: %v", p.Name)})
return
}
if ok := totp.Validate(p.Code, user.Key); ok == false {
w.Write(api.Response{Status: api.StatusIncorrectCredential, Message: fmt.Sprintf("incorrect OTP code: %v", p.Code)})
return
}
id := r.session.Add(user)
logger.Debugf("login success: user=%v, sessionID=%v", spew.Sdump(user), id)
w.Write(api.Response{
Status: api.StatusOkay,
Data: struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
Admin bool `json:"admin"`
}{
SessionID: id,
ID: user.ID,
Admin: user.Admin,
},
})
}
type loginParam struct {
Name string
Password string
Code string // OTP Authentication Code.
}
func (r *loginParam) UnmarshalJSON(data []byte) error {
v := struct {
Name string `json:"name"`
Password string `json:"password"`
Code string `json:"code"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = loginParam(v)
return r.validate()
}
func (r *loginParam) validate() error {
if len(r.Name) == 0 {
return errors.New("empty name")
}
if len(r.Password) == 0 {
return errors.New("empty password")
}
if len(r.Code) != 6 {
return fmt.Errorf("invalid OTP code: %v", r.Code)
}
return nil
}
func (r *API) logout(w api.ResponseWriter, req *rest.Request) {
p := new(logoutParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("logout request from %v: %v", req.RemoteAddr, spew.Sdump(p))
if r.session.Remove(p.SessionID) == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("logout attempt with an unknown session ID: %v", p.SessionID)})
return
}
logger.Debugf("session removed: sessionID=%v", p.SessionID)
w.Write(api.Response{Status: api.StatusOkay})
}
type logoutParam struct {
SessionID string
}
func (r *logoutParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = logoutParam(v)
return r.validate()
}
func (r *logoutParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
return nil
}
func (r *API) listUser(w api.ResponseWriter, req *rest.Request) {
p := new(listUserParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("listUser request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
if session.(*User).Admin == false {
w.Write(api.Response{Status: api.StatusPermissionDenied, Message: fmt.Sprintf("not allowed session id: %v", p.SessionID)})
return
}
var user []*User
f := func(tx Transaction) (err error) {
user, err = tx.Users(p.Pagination)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to query the user accounts: %v", err.Error())})
return
}
logger.Debugf("queried user accounts: %v", spew.Sdump(user))
w.Write(api.Response{Status: api.StatusOkay, Data: user})
}
type listUserParam struct {
SessionID string
Pagination Pagination
}
func (r *listUserParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
Pagination Pagination `json:"pagination"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = listUserParam(v)
return r.validate()
}
func (r *listUserParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.Pagination.Limit == 0 {
return errors.New("invalid pagination limit")
}
return nil
}
func (r *API) addUser(w api.ResponseWriter, req *rest.Request) {
p := new(addUserParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode params: %v", err.Error())})
return
}
logger.Debugf("addUser request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
if session.(*User).Admin == false {
w.Write(api.Response{Status: api.StatusPermissionDenied, Message: fmt.Sprintf("not allowed session id: %v", p.SessionID)})
return
}
key, err := generateOTPKey(p.Name)
if err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to generate OTP key: %v", err)})
return
}
var user *User
var duplicated bool
f := func(tx Transaction) (err error) {
user, duplicated, err = tx.AddUser(session.(*User).ID, p.Name, key.Secret())
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to add a new user account: %v", err.Error())})
return
}
if duplicated {
w.Write(api.Response{Status: api.StatusDuplicated, Message: fmt.Sprintf("duplicated user account: %v", p.Name)})
return
}
logger.Debugf("added the user account: %v", spew.Sdump(user))
w.Write(api.Response{
Status: api.StatusOkay,
Data: &struct {
User *User `json:"user"`
OTP string `json:"otp"`
}{
User: user,
OTP: key.String(),
},
})
}
type addUserParam struct {
SessionID string
Name string
}
func (r *addUserParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
Name string `json:"name"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = addUserParam(v)
return r.validate()
}
func (r *addUserParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if len(r.Name) == 0 {
return errors.New("empty name")
}
return nil
}
func generateOTPKey(account string) (*otp.Key, error) {
return totp.Generate(totp.GenerateOpts{
Issuer: "Cherry",
AccountName: account,
})
}
func (r *API) updateUser(w api.ResponseWriter, req *rest.Request) {
p := new(updateUserParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode params: %v", err.Error())})
return
}
logger.Debugf("updateUser request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
if session.(*User).Admin == false {
w.Write(api.Response{Status: api.StatusPermissionDenied, Message: fmt.Sprintf("not allowed session id: %v", p.SessionID)})
return
}
var user *User
f := func(tx Transaction) (err error) {
user, err = tx.UpdateUser(session.(*User).ID, p.ID, p.Enabled, p.Admin)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to update a user account: %v", err.Error())})
return
}
if user == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found user to update: %v", p.ID)})
return
}
logger.Debugf("updated the user account: %v", spew.Sdump(user))
w.Write(api.Response{Status: api.StatusOkay, Data: user})
}
type updateUserParam struct {
SessionID string
ID uint64
Enabled *bool
Admin *bool
}
func (r *updateUserParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
Enabled *bool `json:"enabled"`
Admin *bool `json:"admin"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = updateUserParam(v)
return r.validate()
}
func (r *updateUserParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ID == 0 {
return errors.New("invalid user ID")
}
if r.Enabled == nil && r.Admin == nil {
return errors.New("empty parameter")
}
return nil
}
func (r *API) resetOTP(w api.ResponseWriter, req *rest.Request) {
p := new(resetOTPParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode params: %v", err.Error())})
return
}
logger.Debugf("resetOTP request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
if session.(*User).Admin == false {
w.Write(api.Response{Status: api.StatusPermissionDenied, Message: fmt.Sprintf("not allowed session id: %v", p.SessionID)})
return
}
key, err := generateOTPKey(p.Name)
if err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to generate OTP key: %v", err)})
return
}
f := func(tx Transaction) (err error) {
ok, err = tx.ResetOTPKey(p.Name, key.Secret())
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to reset OTP of a user account: %v", err.Error())})
return
}
if ok == false {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found user to reset OTP: %v", p.Name)})
return
}
logger.Debugf("reset OTP of the user account: %v", p.Name)
w.Write(api.Response{Status: api.StatusOkay, Data: key.String()})
}
type resetOTPParam struct {
SessionID string
Name string
}
func (r *resetOTPParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
Name string `json:"name"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = resetOTPParam(v)
return r.validate()
}
func (r *resetOTPParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if len(r.Name) == 0 {
return errors.New("empty name")
}
return nil
}
================================================
FILE: api/ui/vip.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package ui
import (
"encoding/json"
"errors"
"fmt"
"unicode/utf8"
"github.com/superkkt/cherry/api"
"github.com/superkkt/cherry/network"
"github.com/ant0ine/go-json-rest/rest"
"github.com/davecgh/go-spew/spew"
)
type VIPTransaction interface {
VIPs(Pagination) ([]*VIP, error)
AddVIP(requesterID, ipID, activeID, standbyID uint64, desc string) (vip *VIP, duplicated bool, err error)
// RemoveVIP removes a VIP specified by id and then returns information of the VIP before removing. It returns nil if the VIP does not exist.
RemoveVIP(requesterID, vipID uint64) (*VIP, error)
// ToggleVIP swaps active host and standby host of a VIP specified by id and then returns information of the VIP. It returns nil if the VIP does not exist.
ToggleVIP(requesterID, vipID uint64) (*VIP, error)
}
type VIP struct {
ID uint64 `json:"id"`
IP string `json:"ip"` // FIXME: Use a native type.
ActiveHost Host `json:"active_host"`
StandbyHost Host `json:"standby_host"`
Description string `json:"description"`
}
func (r *API) listVIP(w api.ResponseWriter, req *rest.Request) {
p := new(listVIPParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("listVIP request from %v: %v", req.RemoteAddr, spew.Sdump(p))
if _, ok := r.session.Get(p.SessionID); ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var vip []*VIP
f := func(tx Transaction) (err error) {
vip, err = tx.VIPs(p.Pagination)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to query the VIP list: %v", err.Error())})
return
}
logger.Debugf("queried VIP list: %v", spew.Sdump(vip))
w.Write(api.Response{Status: api.StatusOkay, Data: vip})
}
type listVIPParam struct {
SessionID string
Pagination Pagination
}
func (r *listVIPParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
Pagination Pagination `json:"pagination"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = listVIPParam(v)
return r.validate()
}
func (r *listVIPParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.Pagination.Limit == 0 {
return errors.New("invalid pagination limit")
}
return nil
}
func (r *API) addVIP(w api.ResponseWriter, req *rest.Request) {
p := new(addVIPParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("addVIP request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var vip *VIP
var duplicated bool
f := func(tx Transaction) (err error) {
vip, duplicated, err = tx.AddVIP(session.(*User).ID, p.IPID, p.ActiveHostID, p.StandbyHostID, p.Description)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to add a new VIP: %v", err.Error())})
return
}
if duplicated {
w.Write(api.Response{Status: api.StatusDuplicated, Message: fmt.Sprintf("duplicated VIP: ip_id=%v", p.IPID)})
return
}
logger.Debugf("added a new VIP: %v", spew.Sdump(vip))
if err := r.announce(vip.IP, vip.ActiveHost.MAC); err != nil {
// Ignore this error.
logger.Errorf("failed to send ARP announcement: %v", err)
}
w.Write(api.Response{Status: api.StatusOkay, Data: vip})
}
type addVIPParam struct {
SessionID string
IPID uint64
ActiveHostID uint64
StandbyHostID uint64
Description string
}
func (r *addVIPParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
IPID uint64 `json:"ip_id"`
ActiveHostID uint64 `json:"active_host_id"`
StandbyHostID uint64 `json:"standby_host_id"`
Description string `json:"description"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = addVIPParam(v)
return r.validate()
}
func (r *addVIPParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ActiveHostID == 0 {
return errors.New("invalid active host id")
}
if r.StandbyHostID == 0 {
return errors.New("invalid standby host id")
}
if r.ActiveHostID == r.StandbyHostID {
return errors.New("same host for the active and standby")
}
if utf8.RuneCountInString(r.Description) > 255 {
return errors.New("too long description")
}
return nil
}
func (r *API) removeVIP(w api.ResponseWriter, req *rest.Request) {
p := new(removeVIPParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("removeVIP request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var vip *VIP
f := func(tx Transaction) (err error) {
vip, err = tx.RemoveVIP(session.(*User).ID, p.ID)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to remove a VIP: %v", err.Error())})
return
}
if vip == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found VIP to remove: %v", p.ID)})
return
}
logger.Debugf("removed the VIP: %v", spew.Sdump(vip))
if err := r.announce(vip.IP, network.NullMAC.String()); err != nil {
// Ignore this error.
logger.Errorf("failed to send ARP announcement: %v", err)
}
w.Write(api.Response{Status: api.StatusOkay})
}
type removeVIPParam struct {
SessionID string
ID uint64
}
func (r *removeVIPParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = removeVIPParam(v)
return r.validate()
}
func (r *removeVIPParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ID == 0 {
return errors.New("invalid VIP id")
}
return nil
}
func (r *API) toggleVIP(w api.ResponseWriter, req *rest.Request) {
p := new(toggleVIPParam)
if err := req.DecodeJsonPayload(p); err != nil {
w.Write(api.Response{Status: api.StatusInvalidParameter, Message: fmt.Sprintf("failed to decode param: %v", err.Error())})
return
}
logger.Debugf("toggleVIP request from %v: %v", req.RemoteAddr, spew.Sdump(p))
session, ok := r.session.Get(p.SessionID)
if ok == false {
w.Write(api.Response{Status: api.StatusUnknownSession, Message: fmt.Sprintf("unknown session id: %v", p.SessionID)})
return
}
var vip *VIP
f := func(tx Transaction) (err error) {
vip, err = tx.ToggleVIP(session.(*User).ID, p.ID)
return err
}
if err := r.DB.Exec(f); err != nil {
w.Write(api.Response{Status: api.StatusInternalServerError, Message: fmt.Sprintf("failed to toggle a VIP: %v", err.Error())})
return
}
if vip == nil {
w.Write(api.Response{Status: api.StatusNotFound, Message: fmt.Sprintf("not found VIP to toggle: %v", p.ID)})
return
}
logger.Debugf("toggled the VIP: %v", spew.Sdump(vip))
if err := r.announce(vip.IP, vip.ActiveHost.MAC); err != nil {
// Ignore this error.
logger.Errorf("failed to send ARP announcement: %v", err)
}
w.Write(api.Response{Status: api.StatusOkay})
}
type toggleVIPParam struct {
SessionID string
ID uint64
}
func (r *toggleVIPParam) UnmarshalJSON(data []byte) error {
v := struct {
SessionID string `json:"session_id"`
ID uint64 `json:"id"`
}{}
if err := json.Unmarshal(data, &v); err != nil {
return err
}
*r = toggleVIPParam(v)
return r.validate()
}
func (r *toggleVIPParam) validate() error {
if len(r.SessionID) != 64 {
return errors.New("invalid session id")
}
if r.ID == 0 {
return errors.New("invalid VIP id")
}
return nil
}
================================================
FILE: cmd/cherry/cherry.yaml
================================================
default:
port: 6633
# The logger will only write log messages whose level is equal to or higher than log_level.
# Lower log level is more verbose. (DEBUG < INFO < WARNING < ERROR < CRITICAL)
# This log_level value can be dynamically changed without restarting the daemon.
log_level: "INFO"
# North-bound applications separated by comma. They will receive a packet in order they appear.
applications: "DHCP, VirtualIP, Discovery, Monitor, ProxyARP, L2Switch, Announcer"
# Email address that will be notified when an abnormal events occur.
admin_email: "name@domain.com"
# Default VLAN ID. All switches should have this VLAN ID on all OF ports.
vlan_id: 1000
mysql:
# host:port[,host:port,host:port,...]
addr: "localhost:3306"
username: "username"
password: "password"
name: "dbname"
rest:
port: 7070
tls: true
cert_file: "/your_tls_cert_file"
key_file: "/your_tls_key_file"
================================================
FILE: cmd/cherry/main.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.
* Kitae Kim <superkkt@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package main
import (
"context"
"flag"
"fmt"
"net"
"os"
"os/signal"
"runtime"
"strings"
"syscall"
"time"
"github.com/superkkt/cherry"
"github.com/superkkt/cherry/api"
"github.com/superkkt/cherry/api/core"
"github.com/superkkt/cherry/database"
"github.com/superkkt/cherry/election"
"github.com/superkkt/cherry/log"
"github.com/superkkt/cherry/network"
"github.com/superkkt/cherry/northbound"
"github.com/fsnotify/fsnotify"
"github.com/pkg/errors"
"github.com/superkkt/go-logging"
"github.com/superkkt/viper"
)
const (
programName = "cherry"
programVersion = cherry.Version
defaultLogLevel = logging.INFO
)
var (
logger = logging.MustGetLogger("main")
loggerLeveled logging.LeveledBackend
showVersion = flag.Bool("version", false, "Show program version and exit")
defaultConfigFile = flag.String("config", fmt.Sprintf("/usr/local/etc/%v.yaml", programName), "absolute path of the configuration file")
)
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
flag.Parse()
if *showVersion {
fmt.Printf("Version: %v\n", programVersion)
os.Exit(0)
}
initConfig()
if err := initLog(getLogLevel(viper.GetString("default.log_level"))); err != nil {
logger.Fatalf("failed to init log: %v", err)
}
ctx, cancel := context.WithCancel(context.Background())
db, err := database.NewMySQL()
if err != nil {
logger.Fatalf("failed to init MySQL database: %v", err)
}
observer := initElectionObserver(ctx, db)
controller := network.NewController(db)
initAPIServer(observer, controller)
manager, err := createAppManager(db)
if err != nil {
logger.Fatalf("failed to create application manager: %v", err)
}
manager.AddEventSender(controller)
initSignalHandler(controller, manager, cancel)
listen(ctx, viper.GetInt("default.port"), controller, observer)
}
func initConfig() {
viper.SetConfigFile(*defaultConfigFile)
// Read the config file.
if err := viper.ReadInConfig(); err != nil {
logger.Fatalf("failed to read the config file: %v", err)
}
// Watching and re-reading config file whenever it changes.
viper.OnConfigChange(func(e fsnotify.Event) {
// Ignore the WRITE operation to avoid reading empty config.
if e.Op != fsnotify.Write {
return
}
if loggerLeveled != nil {
// Set log level for all modules
loggerLeveled.SetLevel(getLogLevel(viper.GetString("default.log_level")), "")
}
})
viper.WatchConfig()
if err := validateConfig(); err != nil {
logger.Fatalf("failed to validate the configuration: %v", err)
}
}
func validateConfig() error {
if port := viper.GetInt("default.port"); port <= 0 || port > 0xFFFF {
return errors.New("invalid default.port")
}
if len(viper.GetString("default.log_level")) == 0 {
return errors.New("invalid default.log_level")
}
if len(viper.GetString("default.applications")) == 0 {
return errors.New("invalid default.applications")
}
if len(viper.GetString("default.admin_email")) == 0 {
return errors.New("invalid default.admin_email")
}
vlanID := viper.GetInt("default.vlan_id")
if vlanID < 0 || vlanID > 4095 {
return errors.New("invalid default.vlan_id in the config file")
}
return nil
}
func initElectionObserver(ctx context.Context, db *database.MySQL) *election.Observer {
observer := election.New(db)
go func() {
if err := observer.Run(ctx); err != nil {
logger.Fatalf("failed to run the election observer: %v", err)
}
logger.Debugf("election observer terminated")
}()
return observer
}
func initAPIServer(observer *election.Observer, controller *network.Controller) {
go func() {
s := api.Server{}
s.Port = uint16(viper.GetInt("rest.port"))
if viper.GetBool("rest.tls") == true {
s.TLS.Cert = viper.GetString("rest.cert_file")
s.TLS.Key = viper.GetString("rest.key_file")
}
s.Observer = observer
s.Controller = controller
srv := &core.API{Server: s}
if err := srv.Serve(); err != nil {
logger.Fatalf("failed to run the API server: %v", err)
}
}()
}
func initSignalHandler(controller *network.Controller, manager *northbound.Manager, cancel context.CancelFunc) {
go func() {
c := make(chan os.Signal, 5)
// All incoming signals will be transferred to the channel
signal.Notify(c)
// Infinte loop.
for {
s := <-c
if s == syscall.SIGTERM || s == syscall.SIGINT {
// Graceful shutdown
logger.Warning("Shutting down...")
cancel()
// Timeout for cancelation
time.Sleep(5 * time.Second)
os.Exit(0)
} else if s == syscall.SIGHUP {
fmt.Println("* Controller status:")
fmt.Println(controller.String())
fmt.Printf("\n* Manager status:\n")
fmt.Println(manager.String())
}
}
}()
}
func initLog(level logging.Level) error {
backend, err := log.NewSyslog(programName)
if err != nil {
return err
}
backend = logging.NewBackendFormatter(backend, logging.MustStringFormatter(`%{level}: %{shortpkg}.%{shortfunc}: %{message}`))
loggerLeveled = logging.AddModuleLevel(backend)
// Set log level for all modules
loggerLeveled.SetLevel(level, "")
logging.SetBackend(loggerLeveled)
return nil
}
func getLogLevel(level string) logging.Level {
level = strings.ToUpper(level)
ret, err := logging.LogLevel(level)
if err != nil {
logger.Infof("invalid log level=%v, defaulting to %v..", level, defaultLogLevel)
return defaultLogLevel
}
return ret
}
func listen(ctx context.Context, port int, controller *network.Controller, observer *election.Observer) {
type KeepAliver interface {
SetKeepAlive(keepalive bool) error
SetKeepAlivePeriod(d time.Duration) error
}
listener, err := net.Listen("tcp", fmt.Sprintf(":%v", port))
if err != nil {
logger.Errorf("failed to listen on %v port: %v", port, err)
return
}
defer listener.Close()
// Connection dispatcher.
f := func(c chan<- net.Conn) {
for {
conn, err := listener.Accept()
if err != nil {
logger.Errorf("failed to accept a new connection: %v", err)
continue
}
logger.Infof("new device is connected from %v", conn.RemoteAddr())
// Only the master controller can serve the connections!
if observer.IsMaster() == false {
logger.Warningf("disconnecting the newly connected device (%v) because we are not the master controller!", conn.RemoteAddr())
conn.Close()
continue
}
// Pass the new connection into the backlog queue.
c <- conn
}
}
backlog := make(chan net.Conn, 32)
go f(backlog)
// Infinite loop
for {
select {
case <-ctx.Done():
logger.Debug("terminating the main listener loop...")
return
case conn := <-backlog:
logger.Debug("fetching a new connection from the backlog..")
if v, ok := conn.(KeepAliver); ok {
logger.Debug("trying to enable socket keepalive..")
if err := v.SetKeepAlive(true); err == nil {
logger.Debug("setting socket keepalive period...")
// Makes a broken connection will be disconnected within 45 seconds.
// http://felixge.de/2014/08/26/tcp-keepalive-with-golang.html
v.SetKeepAlivePeriod(time.Duration(5) * time.Second)
} else {
logger.Errorf("failed to enable socket keepalive: %v", err)
}
}
controller.AddConnection(ctx, conn)
}
}
}
func createAppManager(db *database.MySQL) (*northbound.Manager, error) {
manager, err := northbound.NewManager(db)
if err != nil {
return nil, err
}
apps, err := parseApplications()
if err != nil {
return nil, errors.Wrap(err, "failed to parse applications")
}
for _, v := range apps {
if err := manager.Enable(v); err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("enabling %v", v))
}
}
return manager, nil
}
func parseApplications() ([]string, error) {
// Remove spaces, and then split it using comma
tokens := strings.Split(strings.Replace(viper.GetString("default.applications"), " ", "", -1), ",")
if len(tokens) == 0 {
return nil, errors.New("empty application")
}
return tokens, nil
}
================================================
FILE: cmd/walnut/main.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.
*
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package main
import (
"flag"
"fmt"
"math/rand"
"os"
"os/signal"
"runtime"
"strings"
"syscall"
"time"
"github.com/superkkt/cherry"
"github.com/superkkt/cherry/api"
"github.com/superkkt/cherry/api/ui"
"github.com/superkkt/cherry/database"
"github.com/superkkt/cherry/ldap"
"github.com/superkkt/cherry/log"
"github.com/fsnotify/fsnotify"
"github.com/superkkt/go-logging"
"github.com/superkkt/viper"
)
const (
programName = "walnut"
programVersion = cherry.Version
defaultLogLevel = logging.INFO
)
var (
logger = logging.MustGetLogger("main")
loggerLeveled logging.LeveledBackend
showHelp = flag.Bool("help", false, "show this help and exit")
showVersion = flag.Bool("version", false, "show program version and exit")
defaultConfigFile = flag.String("config", fmt.Sprintf("/usr/local/etc/%v.yaml", programName), "absolute path of the configuration file")
)
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
rand.Seed(time.Now().Unix())
}
func main() {
parseCmdLines()
initConfig()
initLog()
initAPIServer()
waitSignal()
logger.Infof("%v (version %v) shutdown complete!", programName, programVersion)
}
// Handle the command-line arguments.
func parseCmdLines() {
flag.Parse()
if *showHelp {
flag.Usage()
os.Exit(0)
}
if *showVersion {
fmt.Printf("%v v%v\n", programName, programVersion)
os.Exit(0)
}
}
func initConfig() {
viper.SetConfigFile(*defaultConfigFile)
// Read the config file.
if err := viper.ReadInConfig(); err != nil {
logger.Fatalf("failed to read the config file: %v", err)
}
// Watching and re-reading config file whenever it changes.
viper.OnConfigChange(func(e fsnotify.Event) {
// Ignore all the fsnotify operations except WRITE to avoid reading empty config.
if e.Op != fsnotify.Write {
return
}
logger.Infof("config file changed: %v", e.Name)
// Set log level for all modules
loggerLeveled.SetLevel(getLogLevel(), "")
})
viper.WatchConfig()
if err := validateConfig(); err != nil {
logger.Fatalf("invalid configuration: %v", err)
}
}
// validateConfig validates essential configurations.
func validateConfig() error {
// TODO: Add validation you want.
return nil
}
func initLog() {
logDriver := viper.GetString("log.driver")
var err error
var backend logging.Backend
switch strings.ToLower(logDriver) {
case "stderr":
backend = logging.NewLogBackend(os.Stderr, "", 0)
backend = logging.NewBackendFormatter(backend, logging.MustStringFormatter(`%{time} [%{pid}] %{level}: %{shortpkg}.%{longfunc}: %{message}`))
case "syslog":
backend, err = log.NewSyslog(programName)
if err != nil {
logger.Fatalf("failed to init log: %v", err)
}
backend = logging.NewBackendFormatter(backend, logging.MustStringFormatter(`%{level}: %{shortpkg}.%{longfunc}: %{message}`))
default:
logger.Fatalf("unsupported log driver: %v", logDriver)
}
loggerLeveled = logging.AddModuleLevel(backend)
// Set log level for all modules
loggerLeveled.SetLevel(getLogLevel(), "")
logging.SetBackend(loggerLeveled)
}
func getLogLevel() logging.Level {
level := strings.ToUpper(viper.GetString("log.level"))
ret, err := logging.LogLevel(level)
if err != nil {
logger.Errorf("invalid log.level=%v, defaulting to %v..", level, defaultLogLevel)
return defaultLogLevel
}
return ret
}
func initDatabase() *database.MySQL {
db, err := database.NewMySQL()
if err != nil {
logger.Fatalf("failed to init MySQL database: %v", err)
}
return db
}
func initCoreSDK() *coreSDK {
client, err := newCoreSDK(viper.GetString("core_api_url"))
if err != nil {
logger.Fatalf("failed to init the core API's SDK: %v", err)
}
return client
}
func initLDAPClient() *ldap.Client {
return ldap.New(viper.Sub("ldap"), 5)
}
func initAPIServer() {
go func() {
s := api.Server{}
s.Port = uint16(viper.GetInt("rest.port"))
if viper.GetBool("rest.tls") == true {
s.TLS.Cert = viper.GetString("rest.cert_file")
s.TLS.Key = viper.GetString("rest.key_file")
}
sdk := initCoreSDK()
s.Observer = sdk
s.Controller = sdk
srv := &ui.API{Server: s, DB: initDatabase(), LDAP: initLDAPClient()}
if err := srv.Serve(); err != nil {
logger.Fatalf("failed to run the API server: %v", err)
}
}()
}
// waitSignal waits until we receive SIGTERM or SIGINT signals.
func waitSignal() {
c := make(chan os.Signal, 1)
// Following signals will be transferred to the channel c.
signal.Notify(c, syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP, syscall.SIGUSR1, syscall.SIGUSR2, syscall.SIGPIPE)
// Infinite loop.
for {
s := <-c
switch s {
case syscall.SIGTERM, syscall.SIGINT:
logger.Infof("caught %v signal: shutting down...", s)
return
default:
logger.Infof("caught %v signal: ignored!", s)
}
}
}
================================================
FILE: cmd/walnut/sdk.go
================================================
/*
* Copyright 2019 Samjung Data Service, Inc. All Rights Reserved.
*
* Authors:
* Kitae Kim <superkkt@sds.co.kr>
* Donam Kim <donam.kim@sds.co.kr>
* Jooyoung Kang <jooyoung.kang@sds.co.kr>
* Changjin Choi <ccj9707@sds.co.kr>
*/
package main
import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"time"
)
type coreSDK struct {
baseURL string
client *http.Client
}
func newCoreSDK(baseURL string) (*coreSDK, error) {
if _, err := url.Parse(baseURL); err != nil {
return nil, err
}
return &coreSDK{
baseURL: baseURL,
client: &http.Client{
Transport: &http.Transport{
TLSHandshakeTimeout: 10 * time.Second,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
Timeout: 30 * time.Second,
},
}, nil
}
func (r *coreSDK) Announce(ip net.IP, mac net.HardwareAddr) error {
arg := &struct {
IP string `json:"ip"`
MAC string `json:"mac"`
}{
IP: ip.String(),
MAC: mac.String(),
}
return r.call("POST", "/api/v1/announce", arg, nil)
}
func (r *coreSDK) RemoveFlows() error {
return r.call("POST", "/api/v1/remove", nil, nil)
}
func (r *coreSDK) RemoveFlowsByMAC(mac net.HardwareAddr) error {
arg := &struct {
MAC string `json:"mac"`
}{mac.String()}
return r.call("POST", "/api/v1/remove", arg, nil)
}
func (r *coreSDK) IsMaster() bool {
res := new(struct {
Master bool `json:"master"`
})
if err := r.call("POST", "/api/v1/status", nil, res); err != nil {
return false
}
return res.Master
}
func (r *coreSDK) call(method, command string, param interface{}, result interface{}) error {
payload, err := json.Marshal(param)
if err != nil {
return err
}
logger.Debugf("REST request: %v", string(payload))
req, err := http.NewRequest(method, r.baseURL+command, bytes.NewReader(payload))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
resp, err := r.client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return fmt.Errorf("unexpected HTTP status code: %v", resp.StatusCode)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
logger.Debugf("REST response: %v", string(body))
res := new(struct {
Status int `json:"status"`
Message string `json:"message"`
Data json.RawMessage `json:"data"`
})
if err := json.Unmarshal(body, res); err != nil {
return err
}
if res.Status != 200 {
return fmt.Errorf("unexpected response status: status=%v, message=%v", res.Status, res.Message)
}
if result == nil {
// Ignore the query result.
return nil
}
return json.Unmarshal(res.Data, &result)
}
================================================
FILE: cmd/walnut/walnut.yaml
================================================
# NOTE:
#
# Parameters marked as a DYNAMIC can be dynamically updated without restarting the daemon.
log:
# (DYNAMIC)
# The logger will only write log messages whose level is equal to or higher
# than this level. It should be one of DEBUG, INFO, WARNING, ERROR or CRITICAL.
# Lower log level is more verbose. (DEBUG < INFO < WARNING < ERROR < CRITICAL)
level: "INFO"
# log_driver can be one of stderr or syslog.
driver: "stderr"
mysql:
# host:port[,host:port,host:port,...]
addr: "localhost:3306"
username: "username"
password: "password"
name: "database"
rest:
port: 4500
tls: true
cert_file: "/your_tls_cert_file"
key_file: "/your_tls_key_file"
core_api_url: "http://localhost:7070"
ldap:
addr: "localhost:636"
base_dn: "DC=direct,DC=co,DC=kr"
admin:
name: "name"
password: "password"
attr:
login: "sAMAccountName"
================================================
FILE: database/mysql.go
================================================
/*
* Cherry - An OpenFlow Controller
*
* Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.
* Kitae Kim <superkkt@sds.co.kr>
*
* 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 2 of the License, or
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package database
import (
"database/sql"
"encoding/binary"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"math"
"math/rand"
"net"
"runtime"
"strings"
"time"
"github.com/superkkt/cherry/api/ui"
"github.com/superkkt/cherry/network"
"github.com/superkkt/cherry/northbound/app/announcer"
"github.com/superkkt/cherry/northbound/app/dhcp"
"github.com/superkkt/cherry/northbound/app/discovery"
"github.com/superkkt/cherry/northbound/app/virtualip"
"github.com/go-sql-driver/mysql"
"github.com/superkkt/go-logging"
"github.com/superkkt/viper"
)
const (
maxDeadlockRetry = 5
deadlockErrCode uint16 = 1213
duplicatedErrCode uint16 = 1062
foreignkeyErrCode uint16 = 1451
clusterDialerNetwork = "cluster"
)
var (
logger = logging.MustGetLogger("database")
maxIdleConn = runtime.NumCPU()
maxOpenConn = maxIdleConn * 2
)
type MySQL struct {
db *sql.DB
random *rand.Rand
}
func NewMySQL() (*MySQL, error) {
addr := viper.GetString("mysql.addr")
if err := validateClusterAddr(addr); err != nil {
return nil, err
}
// Register the custom dialer.
mysql.RegisterDial(clusterDialerNetwork, clusterDialer)
param := "readTimeout=1m&writeTimeout=1m&parseTime=true&loc=Local&maxAllowedPacket=0"
dsn := fmt.Sprintf("%v:%v@%v(%v)/%v?%v", viper.GetString("mysql.username"), viper.GetString("mysql.password"), clusterDialerNetwork, addr, viper.GetString("mysql.name"), param)
db, err := sql.Open("mysql", dsn)
if err != nil {
return nil, err
}
db.SetMaxOpenConns(maxOpenConn)
db.SetMaxIdleConns(maxIdleConn)
// Make sure that all the connections are established to a same node, instead of distributing them into multiple nodes.
db.SetConnMaxLifetime(5 * time.Minute)
if err := db.Ping(); err != nil {
return nil, err
}
return &MySQL{
db: db,
random: rand.New(&randomSource{src: rand.NewSource(time.Now().Unix())}),
}, nil
}
func validateClusterAddr(addr string) error {
if len(addr) == 0 {
return errors.New("empty cluster address")
}
token := strings.Split(strings.Replace(addr, " ", "", -1), ",")
if len(token) == 0 {
return fmt.Errorf("invalid cluster address: %v", addr)
}
for _, v := range token {
if _, err := net.ResolveTCPAddr("tcp", v); err != nil {
return fmt.Errorf("invalid cluster address: %v: %v", v, err)
}
}
return nil
}
// clusterDialer tries to sequentially connect to each hosts from the address in the
// order of their appearance and then returns the first successfully connected one.
func clusterDialer(addr string) (net.Conn, error) {
token := strings.Split(strings.Replace(addr, " ", "", -1), ",")
for _, v := range token {
logger.Debugf("dialing to %v", v)
conn, err := net.DialTimeout("tcp", v, 5*time.Second)
if err == nil {
// Connected!
logger.Debugf("successfully connected to %v", v)
return conn, nil
}
logger.Errorf("failed to dial: %v", err)
}
return nil, errors.New("failed to dial: no available cluster node")
}
func isDeadlock(err error) bool {
e, ok := err.(*mysql.MySQLError)
if !ok {
return false
}
return e.Number == deadlockErrCode
}
func isDuplicated(err error) bool {
e, ok := err.(*mysql.MySQLError)
if !ok {
return false
}
return e.Number == duplicatedErrCode
}
func isForeignkeyErr(err error) bool {
e, ok := err.(*mysql.MySQLError)
if !ok {
return false
}
return e.Number == foreignkeyErrCode
}
func (r *MySQL) query(f func(*sql.Tx) error) error {
deadlockRetry := 0
for {
tx, err := r.db.Begin()
if err != nil {
return err
}
err = f(tx)
// Success?
if err == nil {
// Yes! but Commit also may raise an error.
err = tx.Commit()
// Success?
if err == nil {
// Transaction committed successfully!
return nil
}
// Fallthrough!
}
// No! query failed.
tx.Rollback()
// Need to retry due to a deadlock?
if !isDeadlock(err) || deadlockRetry >= maxDeadlockRetry {
// No, do not retry and just return the error.
return err
}
// Yes, a deadlock occurrs. Re-execute the queries again after some sleep!
logger.Infof("query failed due to a deadlock: caller=%v", caller())
time.Sleep(time.Duration(rand.Int31n(500)) * time.Millisecond)
deadlockRetry++
}
}
func caller() string {
pc, file, line, ok := runtime.Caller(2)
if !ok {
return "unknown"
}
f := runtime.FuncForPC(pc)
if f == nil {
return fmt.Sprintf("%v:%v", file, line)
}
return fmt.Sprintf("%v (%v:%v)", f.Name(), file, line)
}
func (r *MySQL) MAC(ip net.IP) (mac net.HardwareAddr, ok bool, err error) {
if ip == nil {
panic("IP address is nil")
}
f := func(tx *sql.Tx) error {
// Union query from both vip and host tables
qry := `(SELECT B.mac, B.enabled
FROM vip
A JOIN host B ON A.active_host_id = B.id
JOIN ip C ON A.ip_id = C.id
WHERE C.address = INET_ATON(?)
)
UNION ALL
(SELECT A.mac, A.enabled
FROM host A
JOIN ip B ON A.ip_id = B.id
WHERE B.address = INET_ATON(?)
)
LIMIT 1`
row, err := tx.Query(qry, ip.String(), ip.String())
if err != nil {
return err
}
defer row.Close()
// Unknown IP address?
if !row.Next() {
return nil
}
if err := row.Err(); err != nil {
return err
}
var v []byte
var enabled bool
if err := row.Scan(&v, &enabled); err != nil {
return err
}
if v == nil || len(v) != 6 {
return errors.New("invalid MAC address")
}
if enabled == false {
return nil
}
mac = net.HardwareAddr(v)
ok = true
return nil
}
err = r.query(f)
return mac, ok, err
}
func (r *MySQL) Location(mac net.HardwareAddr) (dpid string, port uint32, status network.LocationStatus, err error) {
if mac == nil {
panic("MAC address is nil")
}
f := func(tx *sql.Tx) error {
// Initial value.
status = network.LocationUnregistered
var portID sql.NullInt64
qry := "SELECT `port_id` FROM `host` WHERE `mac` = ? ORDER BY `port_id` DESC LOCK IN SHARE MODE"
if err := tx.QueryRow(qry, []byte(mac)).Scan(&portID); err != nil {
// Unregistered host?
if err == sql.ErrNoRows {
return nil
} else {
return err
}
}
// NULL port ID?
if portID.Valid == false {
// The node is registered, but we don't know its physical location yet.
status = network.LocationUndiscovered
return nil
}
qry = "SELECT B.`dpid`, A.`number` FROM `port` A JOIN `switch` B ON A.`switch_id` = B.`id` WHERE A.`id` = ?"
if err := tx.QueryRow(qry, portID.Int64).Scan(&dpid, &port); err != nil {
if err == sql.ErrNoRows { // FIXME: Is this possible?
return nil
} else {
return err
}
}
status = network.LocationDiscovered
return nil
}
if err := r.query(f); err != nil {
return "", 0, network.LocationUnregistered, err
}
return dpid, port, status, nil
}
func (r *MySQL) TogglePortVIP(swDPID uint64, portNum uint16) (result []virtualip.Address, err error) {
f := func(tx *sql.Tx) error {
portID, err := portID(tx, swDPID, portNum)
if err != nil {
return err
}
vips, err := getPortVIPs(tx, portID)
if err != nil {
return err
}
for _, v := range vips {
if err := swapVIPHosts(tx, v); err != nil {
return err
}
// Get standby's MAC address as the standby host will be active soon!
mac, err := hostMAC(tx, v.standby)
if err != nil {
return err
}
result = append(result, virtualip.Address{IP: v.address, MAC: mac})
}
return nil
}
if err = r.query(f); err != nil {
return nil, err
}
return result, nil
}
func (r *MySQL) ToggleDeviceVIP(swDPID uint64) (result []virtualip.Address, err error) {
f := func(tx *sql.Tx) error {
vips, err := getDeviceVIPs(tx, swDPID)
if err != nil {
return err
}
for _, v := range vips {
if err := swapVIPHosts(tx, v); err != nil {
return err
}
// Get standby's MAC address as the standby host will be active soon!
mac, err := hostMAC(tx, v.standby)
if err != nil {
return err
}
result = append(result, virtualip.Address{IP: v.address, MAC: mac})
}
return nil
}
if err = r.query(f); err != nil {
return nil, err
}
return result, nil
}
func portID(tx *sql.Tx, swDPID uint64, portNum uint16) (uint64, error) {
qry := `SELECT A.id
FROM port A
JOIN switch B ON A.switch_id = B.id
WHERE A.number = ? AND B.dpid = ?
LOCK IN SHARE MODE`
row, err := tx.Query(qry, portNum, swDPID)
if err != nil {
return 0, err
}
defer row.Close()
// Empty row?
if !row.Next() {
return 0, fmt.Errorf("unknown switch port (DPID=%v, Number=%v)", swDPID, portNum)
}
var id uint64
if err := row.Scan(&id); err != nil {
return 0, err
}
return id, nil
}
type vip struct {
id uint64
address net.IP
active uint64
standby uint64
}
func getPortVIPs(tx *sql.Tx, portID uint64) (result []vip, err error) {
qry := `SELECT A.id, INET_NTOA(C.address), A.active_host_id, A.standby_host_id
FROM vip A
JOIN host B ON A.active_host_id = B.id
JOIN ip C ON A.ip_id = C.id
WHERE B.port_id = ?
FOR UPDATE`
rows, err := tx.Query(qry, portID)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var id, active, standby uint64
var address string
if err := rows.Scan(&id, &address, &active, &standby); err != nil {
return nil, err
}
ip := net.ParseIP(address)
if ip == nil {
return nil, fmt.Errorf("invalid IPv4 address: %v", address)
}
result = append(result, vip{id, ip, active, standby})
}
if err := rows.Err(); err != nil {
return nil, err
}
return result, nil
}
func getDeviceVIPs(tx *sql.Tx, swDPID uint64) (result []vip, err error) {
qry := `SELECT A.id, INET_NTOA(E.address), A.active_host_id, A.standby_host_id
FROM vip A
JOIN host B ON A.active_host_id = B.id
JOIN port C ON B.port_id = C.id
JOIN switch D ON D.id = C.switch_id
JOIN ip E ON E.id = A.ip_id
WHERE D.dpid = ?
FOR UPDATE`
rows, err := tx.Query(qry, swDPID)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var id, active, standby uint64
var address string
if err := rows.Scan(&id, &address, &active, &standby); err != nil {
return nil, err
}
ip := net.ParseIP(address)
if ip == nil {
return nil, fmt.Errorf("invalid IPv4 address: %v", address)
}
result = append(result, vip{id, ip, active, standby})
}
if err := rows.Err(); err != nil {
return nil, err
}
return result, nil
}
func swapVIPHosts(tx *sql.Tx, v vip) error {
qry := "UPDATE vip SET active_host_id = ?, standby_host_id = ? WHERE id = ?"
// Swap active and standby hosts
_, err := tx.Exec(qry, v.standby, v.active, v.id)
if err != nil {
return err
}
if err := updateARPTableEntryByVIP(tx, v.id, false); err != nil {
return err
}
return nil
}
func hostMAC(tx *sql.Tx, hostID uint64) (net.HardwareAddr, error) {
row, err := tx.Query("SELECT HEX(mac) FROM host WHERE id = ?", hostID)
if err != nil {
return nil, err
}
defer row.Close()
// Empty row?
if !row.Next() {
return nil, fmt.Errorf("unknown host (ID=%v)", hostID)
}
var v string
if err := row.Scan(&v); err != nil {
return nil, err
}
mac, err := decodeMAC(v)
if err != nil {
return nil, err
}
return mac, nil
}
// GetUndiscoveredHosts returns IP addresses whose physical location is still
// undiscovered or staled more than expiration. result can be nil on empty result.
func (r *MySQL) GetUndiscoveredHosts(expiration time.Duration) (result []net.IPNet, err error) {
f := func(tx *sql.Tx) error {
// NOTE: Do not include VIP addresses!
qry := "SELECT IFNULL(INET_NTOA(B.`address`), '0.0.0.0'), IFNULL(C.`mask`, 0) "
qry += "FROM `host` A "
qry += "JOIN `ip` B ON A.`ip_id` = B.`id` "
qry += "JOIN `network` C ON B.`network_id` = C.`id` "
qry += "WHERE A.`port_id` IS NULL OR A.`last_updated_timestamp` < NOW() - INTERVAL ? SECOND"
rows, err := tx.Query(qry, uint64(expiration.Seconds()))
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var addr string
var mask int
if err := rows.Scan(&addr, &mask); err != nil {
return err
}
ip := net.ParseIP(addr)
if ip == nil {
return fmt.Errorf("invalid IP address: %v", addr)
}
if ip.IsUnspecified() {
continue
}
netmask := net.CIDRMask(mask, 32)
if netmask == nil {
return fmt.Errorf("invalid network mask: IP=%v, Mask=%v", addr, mask)
}
result = append(result, net.IPNet{IP: ip, Mask: netmask})
}
return rows.Err()
}
if err = r.query(f); err != nil {
return nil, err
}
return result, nil
}
// UpdateHostLocation updates the physical location of a host, whose MAC and IP
// addresses are matched with mac and ip, to the port identified by swDPID and
// portNum. updated will be true if its location has been actually updated.
func (r *MySQL) UpdateHostLocation(mac net.HardwareAddr, ip net.IP, swDPID uint64, portNum uint16) (updated bool, err error) {
f := func(tx *sql.Tx) error {
hostID, ok, err := getHostID(tx, mac, ip)
if err != nil {
return err
}
// Unknown host?
if !ok {
updated = false
return nil
}
portID, err := portID(tx, swDPID, portNum)
if err != nil {
return err
}
updated, err = updateLocation(tx, hostID, portID)
if err != nil {
return err
}
return nil
}
if err = r.query(f); err != nil {
return false, err
}
return updated, nil
}
func getHostID(tx *sql.Tx, mac net.HardwareAddr, ip net.IP) (hostID uint64, ok bool, err error) {
qry := "SELECT A.`id` "
qry += "FROM `host` A "
qry += "JOIN `ip` B "
qry += "ON A.`ip_id` = B.`id` "
qry += "WHERE A.`mac` = ? AND B.`address` = INET_ATON(?) "
qry += "LOCK IN SHARE MODE"
row, err := tx.Query(qry, []byte(mac), ip.String())
if err != nil {
return 0, false, err
}
defer row.Close()
// Empty row?
if !row.Next() {
return 0, false, nil
}
if err := row.Scan(&hostID); err != nil {
return 0, false, err
}
return hostID, true, nil
}
func updateLocation(tx *sql.Tx, hostID, portID uint64) (updated bool, err error) {
var id uint64
qry := "SELECT `id` FROM `host` WHERE `id` = ? AND `port_id` = ?"
err = tx.QueryRow(qry, hostID, portID).Scan(&id)
// Real error?
if err != nil && err != sql.ErrNoRows {
return false, err
}
// Need to update?
if err == sql.ErrNoRows {
updated = true
}
qry = "UPDATE `host` SET `port_id` = ?, `last_updated_timestamp` = NOW() WHERE `id` = ?"
_, err = tx.Exec(qry, portID, hostID)
if err != nil {
return false, err
}
return updated, nil
}
// ResetHostLocationsByPort sets NULL to the host locations that belong to the
// port specified by swDPID and portNum.
func (r *MySQL) ResetHostLocationsByPort(swDPID uint64, portNum uint16) error {
f := func(tx *sql.Tx) error {
portID, err := portID(tx, swDPID, portNum)
if err != nil {
return err
}
qry := "UPDATE `host` SET `port_id` = NULL WHERE `port_id` = ?"
if _, err := tx.Exec(qry, portID); err != nil {
return err
}
return nil
}
return r.query(f)
}
// ResetHostLocationsByDevice sets NULL to the host locations that belong to the
// device specified by swDPID.
func (r *MySQL) ResetHostLocationsByDevice(swDPID uint64) error {
f := func(tx *sql.Tx) error {
qry := "UPDATE `host` A "
qry += "JOIN `port` B ON A.`port_id` = B.`id` "
qry += "JOIN `switch` C ON B.`switch_id` = C.`id` "
qry += "SET A.`port_id` = NULL "
qry += "WHERE C.`dpid` = ?"
_, err := tx.Exec(qry, swDPID)
if err != nil {
return err
}
return nil
}
return r.query(f)
}
// Elect selects a new master as uid if there is a no existing master that has
// been updated within expiration. elected will be true if this uid has been
// elected as the new master or was already elected.
func (r *MySQL) Elect(uid string, expiration time.Duration) (elected bool, err error) {
qry := "INSERT INTO `master_election` (`id`, `name`, `timestamp`) VALUES (1, ?, NOW()) "
qry += "ON DUPLICATE KEY UPDATE "
qry += fmt.Sprin
gitextract_s279x8yc/ ├── .gitlab-ci.yml ├── Changelog ├── Dockerfile ├── Godeps/ │ ├── Godeps.json │ └── Readme ├── Gopkg.toml ├── LICENSE ├── README.md ├── api/ │ ├── core/ │ │ └── api.go │ ├── response.go │ ├── server.go │ └── ui/ │ ├── api.go │ ├── category.go │ ├── component.go │ ├── group.go │ ├── host.go │ ├── ip.go │ ├── log.go │ ├── network.go │ ├── session.go │ ├── switch.go │ ├── user.go │ └── vip.go ├── cmd/ │ ├── cherry/ │ │ ├── cherry.yaml │ │ └── main.go │ └── walnut/ │ ├── main.go │ ├── sdk.go │ └── walnut.yaml ├── database/ │ ├── mysql.go │ ├── mysql_schema.sql │ └── random.go ├── election/ │ └── election.go ├── graph/ │ ├── graph.go │ └── graph_test.go ├── ldap/ │ ├── client.go │ └── conn.go ├── log/ │ └── syslog.go ├── network/ │ ├── controller.go │ ├── device.go │ ├── error.go │ ├── flow_cache.go │ ├── link.go │ ├── node.go │ ├── of10_session.go │ ├── of13_session.go │ ├── port.go │ ├── reserve.go │ ├── reserve_test.go │ ├── session.go │ └── topology.go ├── northbound/ │ ├── app/ │ │ ├── announcer/ │ │ │ ├── announcer.go │ │ │ └── backoff.go │ │ ├── dhcp/ │ │ │ └── dhcp.go │ │ ├── discovery/ │ │ │ └── discovery.go │ │ ├── l2switch/ │ │ │ ├── storm_controller.go │ │ │ ├── storm_controller_test.go │ │ │ └── switch.go │ │ ├── monitor/ │ │ │ ├── monitor.go │ │ │ └── sendmail.go │ │ ├── processor.go │ │ ├── proxyarp/ │ │ │ ├── arp.go │ │ │ └── error.go │ │ └── virtualip/ │ │ └── virtualip.go │ └── manager.go ├── openflow/ │ ├── action.go │ ├── barrier.go │ ├── config.go │ ├── const.go │ ├── description.go │ ├── echo.go │ ├── error.go │ ├── factory.go │ ├── features.go │ ├── flow_mod.go │ ├── flow_removed.go │ ├── flow_stats.go │ ├── hello.go │ ├── instruction.go │ ├── match.go │ ├── message.go │ ├── of10/ │ │ ├── action.go │ │ ├── barrier.go │ │ ├── config.go │ │ ├── const.go │ │ ├── description.go │ │ ├── echo.go │ │ ├── factory.go │ │ ├── features.go │ │ ├── flow_mod.go │ │ ├── flow_removed.go │ │ ├── flow_stats.go │ │ ├── hello.go │ │ ├── instruction.go │ │ ├── match.go │ │ ├── packet_in.go │ │ ├── packet_out.go │ │ ├── port.go │ │ ├── port_status.go │ │ └── queue.go │ ├── of13/ │ │ ├── action.go │ │ ├── barrier.go │ │ ├── config.go │ │ ├── const.go │ │ ├── echo.go │ │ ├── factory.go │ │ ├── features.go │ │ ├── flow_mod.go │ │ ├── flow_removed.go │ │ ├── hello.go │ │ ├── instruction.go │ │ ├── match.go │ │ ├── multipart_description.go │ │ ├── multipart_flow_stats.go │ │ ├── multipart_port_description.go │ │ ├── multipart_table_features.go │ │ ├── packet_in.go │ │ ├── packet_out.go │ │ ├── port.go │ │ ├── port_status.go │ │ └── queue.go │ ├── packet_in.go │ ├── packet_out.go │ ├── port.go │ ├── port_description.go │ ├── port_status.go │ ├── queue.go │ ├── table_features.go │ └── transceiver/ │ ├── stream.go │ └── transceiver.go ├── protocol/ │ ├── arp.go │ ├── checksum.go │ ├── dhcp.go │ ├── dhcp_test.go │ ├── ethernet.go │ ├── icmp.go │ ├── ipv4.go │ ├── lldp.go │ ├── tcp.go │ └── udp.go ├── vendor/ │ ├── github.com/ │ │ ├── ant0ine/ │ │ │ └── go-json-rest/ │ │ │ ├── LICENSE │ │ │ └── rest/ │ │ │ ├── access_log_apache.go │ │ │ ├── access_log_json.go │ │ │ ├── api.go │ │ │ ├── auth_basic.go │ │ │ ├── content_type_checker.go │ │ │ ├── cors.go │ │ │ ├── doc.go │ │ │ ├── gzip.go │ │ │ ├── if.go │ │ │ ├── json_indent.go │ │ │ ├── jsonp.go │ │ │ ├── middleware.go │ │ │ ├── powered_by.go │ │ │ ├── recorder.go │ │ │ ├── recover.go │ │ │ ├── request.go │ │ │ ├── response.go │ │ │ ├── route.go │ │ │ ├── router.go │ │ │ ├── status.go │ │ │ ├── timer.go │ │ │ └── trie/ │ │ │ └── impl.go │ │ ├── boombuler/ │ │ │ └── barcode/ │ │ │ ├── .gitignore │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── barcode.go │ │ │ ├── qr/ │ │ │ │ ├── alphanumeric.go │ │ │ │ ├── automatic.go │ │ │ │ ├── blocks.go │ │ │ │ ├── encoder.go │ │ │ │ ├── errorcorrection.go │ │ │ │ ├── numeric.go │ │ │ │ ├── qrcode.go │ │ │ │ ├── unicode.go │ │ │ │ └── versioninfo.go │ │ │ ├── scaledbarcode.go │ │ │ └── utils/ │ │ │ ├── base1dcode.go │ │ │ ├── bitlist.go │ │ │ ├── galoisfield.go │ │ │ ├── gfpoly.go │ │ │ ├── reedsolomon.go │ │ │ └── runeint.go │ │ ├── davecgh/ │ │ │ └── go-spew/ │ │ │ ├── LICENSE │ │ │ └── spew/ │ │ │ ├── bypass.go │ │ │ ├── bypasssafe.go │ │ │ ├── common.go │ │ │ ├── config.go │ │ │ ├── doc.go │ │ │ ├── dump.go │ │ │ ├── format.go │ │ │ └── spew.go │ │ ├── fsnotify/ │ │ │ └── fsnotify/ │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── AUTHORS │ │ │ ├── CHANGELOG.md │ │ │ ├── CONTRIBUTING.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── fen.go │ │ │ ├── fsnotify.go │ │ │ ├── inotify.go │ │ │ ├── inotify_poller.go │ │ │ ├── kqueue.go │ │ │ ├── open_mode_bsd.go │ │ │ ├── open_mode_darwin.go │ │ │ └── windows.go │ │ ├── go-sql-driver/ │ │ │ └── mysql/ │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── AUTHORS │ │ │ ├── CHANGELOG.md │ │ │ ├── CONTRIBUTING.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── appengine.go │ │ │ ├── buffer.go │ │ │ ├── collations.go │ │ │ ├── connection.go │ │ │ ├── connection_go18.go │ │ │ ├── const.go │ │ │ ├── driver.go │ │ │ ├── dsn.go │ │ │ ├── errors.go │ │ │ ├── fields.go │ │ │ ├── infile.go │ │ │ ├── packets.go │ │ │ ├── result.go │ │ │ ├── rows.go │ │ │ ├── statement.go │ │ │ ├── transaction.go │ │ │ ├── utils.go │ │ │ ├── utils_go17.go │ │ │ └── utils_go18.go │ │ ├── google/ │ │ │ └── go-cmp/ │ │ │ ├── LICENSE │ │ │ └── cmp/ │ │ │ ├── cmpopts/ │ │ │ │ ├── equate.go │ │ │ │ ├── ignore.go │ │ │ │ ├── sort.go │ │ │ │ ├── struct_filter.go │ │ │ │ └── xform.go │ │ │ ├── compare.go │ │ │ ├── export_panic.go │ │ │ ├── export_unsafe.go │ │ │ ├── internal/ │ │ │ │ ├── diff/ │ │ │ │ │ ├── debug_disable.go │ │ │ │ │ ├── debug_enable.go │ │ │ │ │ └── diff.go │ │ │ │ ├── flags/ │ │ │ │ │ ├── flags.go │ │ │ │ │ ├── toolchain_legacy.go │ │ │ │ │ └── toolchain_recent.go │ │ │ │ ├── function/ │ │ │ │ │ └── func.go │ │ │ │ └── value/ │ │ │ │ ├── pointer_purego.go │ │ │ │ ├── pointer_unsafe.go │ │ │ │ ├── sort.go │ │ │ │ └── zero.go │ │ │ ├── options.go │ │ │ ├── path.go │ │ │ ├── report.go │ │ │ ├── report_compare.go │ │ │ ├── report_reflect.go │ │ │ ├── report_slices.go │ │ │ ├── report_text.go │ │ │ └── report_value.go │ │ ├── hashicorp/ │ │ │ ├── golang-lru/ │ │ │ │ ├── .gitignore │ │ │ │ ├── 2q.go │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── arc.go │ │ │ │ ├── lru.go │ │ │ │ └── simplelru/ │ │ │ │ └── lru.go │ │ │ └── hcl/ │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── appveyor.yml │ │ │ ├── decoder.go │ │ │ ├── hcl/ │ │ │ │ ├── ast/ │ │ │ │ │ ├── ast.go │ │ │ │ │ └── walk.go │ │ │ │ ├── parser/ │ │ │ │ │ ├── error.go │ │ │ │ │ └── parser.go │ │ │ │ ├── scanner/ │ │ │ │ │ └── scanner.go │ │ │ │ ├── strconv/ │ │ │ │ │ └── quote.go │ │ │ │ └── token/ │ │ │ │ ├── position.go │ │ │ │ └── token.go │ │ │ ├── hcl.go │ │ │ ├── json/ │ │ │ │ ├── parser/ │ │ │ │ │ ├── flatten.go │ │ │ │ │ └── parser.go │ │ │ │ ├── scanner/ │ │ │ │ │ └── scanner.go │ │ │ │ └── token/ │ │ │ │ ├── position.go │ │ │ │ └── token.go │ │ │ ├── lex.go │ │ │ └── parse.go │ │ ├── magiconair/ │ │ │ └── properties/ │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── _third_party/ │ │ │ │ └── gopkg.in/ │ │ │ │ └── check.v1/ │ │ │ │ └── LICENSE │ │ │ ├── decode.go │ │ │ ├── doc.go │ │ │ ├── integrate.go │ │ │ ├── lex.go │ │ │ ├── load.go │ │ │ ├── parser.go │ │ │ ├── properties.go │ │ │ └── rangecheck.go │ │ ├── mitchellh/ │ │ │ └── mapstructure/ │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── decode_hooks.go │ │ │ ├── error.go │ │ │ └── mapstructure.go │ │ ├── pelletier/ │ │ │ ├── go-buffruneio/ │ │ │ │ ├── .gitignore │ │ │ │ ├── .travis.yml │ │ │ │ ├── README.md │ │ │ │ └── buffruneio.go │ │ │ └── go-toml/ │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── clean.sh │ │ │ ├── doc.go │ │ │ ├── example-crlf.toml │ │ │ ├── example.toml │ │ │ ├── keysparsing.go │ │ │ ├── lexer.go │ │ │ ├── match.go │ │ │ ├── parser.go │ │ │ ├── position.go │ │ │ ├── query.go │ │ │ ├── querylexer.go │ │ │ ├── queryparser.go │ │ │ ├── test.sh │ │ │ ├── token.go │ │ │ ├── toml.go │ │ │ └── tomltree_conversions.go │ │ ├── pkg/ │ │ │ └── errors/ │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── appveyor.yml │ │ │ ├── errors.go │ │ │ └── stack.go │ │ ├── pquerna/ │ │ │ └── otp/ │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── NOTICE │ │ │ ├── README.md │ │ │ ├── doc.go │ │ │ ├── hotp/ │ │ │ │ └── hotp.go │ │ │ ├── otp.go │ │ │ └── totp/ │ │ │ └── totp.go │ │ ├── spf13/ │ │ │ ├── afero/ │ │ │ │ ├── .travis.yml │ │ │ │ ├── LICENSE.txt │ │ │ │ ├── README.md │ │ │ │ ├── afero.go │ │ │ │ ├── appveyor.yml │ │ │ │ ├── basepath.go │ │ │ │ ├── cacheOnReadFs.go │ │ │ │ ├── const_bsds.go │ │ │ │ ├── const_win_unix.go │ │ │ │ ├── copyOnWriteFs.go │ │ │ │ ├── httpFs.go │ │ │ │ ├── ioutil.go │ │ │ │ ├── mem/ │ │ │ │ │ ├── dir.go │ │ │ │ │ ├── dirmap.go │ │ │ │ │ └── file.go │ │ │ │ ├── memmap.go │ │ │ │ ├── memradix.go │ │ │ │ ├── os.go │ │ │ │ ├── path.go │ │ │ │ ├── readonlyfs.go │ │ │ │ ├── regexpfs.go │ │ │ │ ├── unionFile.go │ │ │ │ └── util.go │ │ │ ├── cast/ │ │ │ │ ├── .gitignore │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── cast.go │ │ │ │ └── caste.go │ │ │ ├── jwalterweatherman/ │ │ │ │ ├── .gitignore │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ └── thatswhyyoualwaysleaveanote.go │ │ │ └── pflag/ │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── bool.go │ │ │ ├── count.go │ │ │ ├── duration.go │ │ │ ├── flag.go │ │ │ ├── float32.go │ │ │ ├── float64.go │ │ │ ├── golangflag.go │ │ │ ├── int.go │ │ │ ├── int32.go │ │ │ ├── int64.go │ │ │ ├── int8.go │ │ │ ├── int_slice.go │ │ │ ├── ip.go │ │ │ ├── ipmask.go │ │ │ ├── ipnet.go │ │ │ ├── string.go │ │ │ ├── string_slice.go │ │ │ ├── uint.go │ │ │ ├── uint16.go │ │ │ ├── uint32.go │ │ │ ├── uint64.go │ │ │ └── uint8.go │ │ └── superkkt/ │ │ ├── go-logging/ │ │ │ ├── .travis.yml │ │ │ ├── CHANGELOG.md │ │ │ ├── CONTRIBUTORS │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── backend.go │ │ │ ├── format.go │ │ │ ├── level.go │ │ │ ├── log_nix.go │ │ │ ├── log_windows.go │ │ │ ├── logger.go │ │ │ ├── memory.go │ │ │ ├── multi.go │ │ │ ├── syslog.go │ │ │ └── syslog_fallback.go │ │ └── viper/ │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── LICENSE │ │ ├── README.md │ │ ├── flags.go │ │ ├── nohup.out │ │ ├── util.go │ │ └── viper.go │ ├── golang.org/ │ │ └── x/ │ │ ├── sys/ │ │ │ ├── AUTHORS │ │ │ ├── CONTRIBUTORS │ │ │ ├── LICENSE │ │ │ ├── PATENTS │ │ │ └── unix/ │ │ │ ├── .gitignore │ │ │ ├── asm.s │ │ │ ├── asm_darwin_386.s │ │ │ ├── asm_darwin_amd64.s │ │ │ ├── asm_darwin_arm.s │ │ │ ├── asm_darwin_arm64.s │ │ │ ├── asm_dragonfly_amd64.s │ │ │ ├── asm_freebsd_386.s │ │ │ ├── asm_freebsd_amd64.s │ │ │ ├── asm_freebsd_arm.s │ │ │ ├── asm_linux_386.s │ │ │ ├── asm_linux_amd64.s │ │ │ ├── asm_linux_arm.s │ │ │ ├── asm_linux_arm64.s │ │ │ ├── asm_linux_mips64x.s │ │ │ ├── asm_linux_ppc64x.s │ │ │ ├── asm_linux_s390x.s │ │ │ ├── asm_netbsd_386.s │ │ │ ├── asm_netbsd_amd64.s │ │ │ ├── asm_netbsd_arm.s │ │ │ ├── asm_openbsd_386.s │ │ │ ├── asm_openbsd_amd64.s │ │ │ ├── asm_solaris_amd64.s │ │ │ ├── bluetooth_linux.go │ │ │ ├── constants.go │ │ │ ├── env_unix.go │ │ │ ├── env_unset.go │ │ │ ├── flock.go │ │ │ ├── flock_linux_32bit.go │ │ │ ├── gccgo.go │ │ │ ├── gccgo_c.c │ │ │ ├── gccgo_linux_amd64.go │ │ │ ├── mkall.sh │ │ │ ├── mkerrors.sh │ │ │ ├── mkpost.go │ │ │ ├── mksyscall.pl │ │ │ ├── mksyscall_solaris.pl │ │ │ ├── mksysctl_openbsd.pl │ │ │ ├── mksysnum_darwin.pl │ │ │ ├── mksysnum_dragonfly.pl │ │ │ ├── mksysnum_freebsd.pl │ │ │ ├── mksysnum_linux.pl │ │ │ ├── mksysnum_netbsd.pl │ │ │ ├── mksysnum_openbsd.pl │ │ │ ├── race.go │ │ │ ├── race0.go │ │ │ ├── sockcmsg_linux.go │ │ │ ├── sockcmsg_unix.go │ │ │ ├── str.go │ │ │ ├── syscall.go │ │ │ ├── syscall_bsd.go │ │ │ ├── syscall_darwin.go │ │ │ ├── syscall_darwin_386.go │ │ │ ├── syscall_darwin_amd64.go │ │ │ ├── syscall_darwin_arm.go │ │ │ ├── syscall_darwin_arm64.go │ │ │ ├── syscall_dragonfly.go │ │ │ ├── syscall_dragonfly_amd64.go │ │ │ ├── syscall_freebsd.go │ │ │ ├── syscall_freebsd_386.go │ │ │ ├── syscall_freebsd_amd64.go │ │ │ ├── syscall_freebsd_arm.go │ │ │ ├── syscall_linux.go │ │ │ ├── syscall_linux_386.go │ │ │ ├── syscall_linux_amd64.go │ │ │ ├── syscall_linux_arm.go │ │ │ ├── syscall_linux_arm64.go │ │ │ ├── syscall_linux_mips64x.go │ │ │ ├── syscall_linux_ppc64x.go │ │ │ ├── syscall_linux_s390x.go │ │ │ ├── syscall_netbsd.go │ │ │ ├── syscall_netbsd_386.go │ │ │ ├── syscall_netbsd_amd64.go │ │ │ ├── syscall_netbsd_arm.go │ │ │ ├── syscall_no_getwd.go │ │ │ ├── syscall_openbsd.go │ │ │ ├── syscall_openbsd_386.go │ │ │ ├── syscall_openbsd_amd64.go │ │ │ ├── syscall_solaris.go │ │ │ ├── syscall_solaris_amd64.go │ │ │ ├── syscall_unix.go │ │ │ ├── types_darwin.go │ │ │ ├── types_dragonfly.go │ │ │ ├── types_freebsd.go │ │ │ ├── types_linux.go │ │ │ ├── types_netbsd.go │ │ │ ├── types_openbsd.go │ │ │ ├── types_solaris.go │ │ │ ├── zerrors_darwin_386.go │ │ │ ├── zerrors_darwin_amd64.go │ │ │ ├── zerrors_darwin_arm.go │ │ │ ├── zerrors_darwin_arm64.go │ │ │ ├── zerrors_dragonfly_amd64.go │ │ │ ├── zerrors_freebsd_386.go │ │ │ ├── zerrors_freebsd_amd64.go │ │ │ ├── zerrors_freebsd_arm.go │ │ │ ├── zerrors_linux_386.go │ │ │ ├── zerrors_linux_amd64.go │ │ │ ├── zerrors_linux_arm.go │ │ │ ├── zerrors_linux_arm64.go │ │ │ ├── zerrors_linux_mips64.go │ │ │ ├── zerrors_linux_mips64le.go │ │ │ ├── zerrors_linux_ppc64.go │ │ │ ├── zerrors_linux_ppc64le.go │ │ │ ├── zerrors_linux_s390x.go │ │ │ ├── zerrors_netbsd_386.go │ │ │ ├── zerrors_netbsd_amd64.go │ │ │ ├── zerrors_netbsd_arm.go │ │ │ ├── zerrors_openbsd_386.go │ │ │ ├── zerrors_openbsd_amd64.go │ │ │ ├── zerrors_solaris_amd64.go │ │ │ ├── zsyscall_darwin_386.go │ │ │ ├── zsyscall_darwin_amd64.go │ │ │ ├── zsyscall_darwin_arm.go │ │ │ ├── zsyscall_darwin_arm64.go │ │ │ ├── zsyscall_dragonfly_amd64.go │ │ │ ├── zsyscall_freebsd_386.go │ │ │ ├── zsyscall_freebsd_amd64.go │ │ │ ├── zsyscall_freebsd_arm.go │ │ │ ├── zsyscall_linux_386.go │ │ │ ├── zsyscall_linux_amd64.go │ │ │ ├── zsyscall_linux_arm.go │ │ │ ├── zsyscall_linux_arm64.go │ │ │ ├── zsyscall_linux_mips64.go │ │ │ ├── zsyscall_linux_mips64le.go │ │ │ ├── zsyscall_linux_ppc64.go │ │ │ ├── zsyscall_linux_ppc64le.go │ │ │ ├── zsyscall_linux_s390x.go │ │ │ ├── zsyscall_netbsd_386.go │ │ │ ├── zsyscall_netbsd_amd64.go │ │ │ ├── zsyscall_netbsd_arm.go │ │ │ ├── zsyscall_openbsd_386.go │ │ │ ├── zsyscall_openbsd_amd64.go │ │ │ ├── zsyscall_solaris_amd64.go │ │ │ ├── zsysctl_openbsd.go │ │ │ ├── zsysnum_darwin_386.go │ │ │ ├── zsysnum_darwin_amd64.go │ │ │ ├── zsysnum_darwin_arm.go │ │ │ ├── zsysnum_darwin_arm64.go │ │ │ ├── zsysnum_dragonfly_amd64.go │ │ │ ├── zsysnum_freebsd_386.go │ │ │ ├── zsysnum_freebsd_amd64.go │ │ │ ├── zsysnum_freebsd_arm.go │ │ │ ├── zsysnum_linux_386.go │ │ │ ├── zsysnum_linux_amd64.go │ │ │ ├── zsysnum_linux_arm.go │ │ │ ├── zsysnum_linux_arm64.go │ │ │ ├── zsysnum_linux_mips64.go │ │ │ ├── zsysnum_linux_mips64le.go │ │ │ ├── zsysnum_linux_ppc64.go │ │ │ ├── zsysnum_linux_ppc64le.go │ │ │ ├── zsysnum_linux_s390x.go │ │ │ ├── zsysnum_netbsd_386.go │ │ │ ├── zsysnum_netbsd_amd64.go │ │ │ ├── zsysnum_netbsd_arm.go │ │ │ ├── zsysnum_openbsd_386.go │ │ │ ├── zsysnum_openbsd_amd64.go │ │ │ ├── zsysnum_solaris_amd64.go │ │ │ ├── ztypes_darwin_386.go │ │ │ ├── ztypes_darwin_amd64.go │ │ │ ├── ztypes_darwin_arm.go │ │ │ ├── ztypes_darwin_arm64.go │ │ │ ├── ztypes_dragonfly_amd64.go │ │ │ ├── ztypes_freebsd_386.go │ │ │ ├── ztypes_freebsd_amd64.go │ │ │ ├── ztypes_freebsd_arm.go │ │ │ ├── ztypes_linux_386.go │ │ │ ├── ztypes_linux_amd64.go │ │ │ ├── ztypes_linux_arm.go │ │ │ ├── ztypes_linux_arm64.go │ │ │ ├── ztypes_linux_mips64.go │ │ │ ├── ztypes_linux_mips64le.go │ │ │ ├── ztypes_linux_ppc64.go │ │ │ ├── ztypes_linux_ppc64le.go │ │ │ ├── ztypes_linux_s390x.go │ │ │ ├── ztypes_netbsd_386.go │ │ │ ├── ztypes_netbsd_amd64.go │ │ │ ├── ztypes_netbsd_arm.go │ │ │ ├── ztypes_openbsd_386.go │ │ │ ├── ztypes_openbsd_amd64.go │ │ │ └── ztypes_solaris_amd64.go │ │ └── text/ │ │ ├── AUTHORS │ │ ├── CONTRIBUTORS │ │ ├── LICENSE │ │ ├── PATENTS │ │ ├── internal/ │ │ │ ├── gen/ │ │ │ │ ├── code.go │ │ │ │ └── gen.go │ │ │ ├── triegen/ │ │ │ │ ├── compact.go │ │ │ │ ├── print.go │ │ │ │ └── triegen.go │ │ │ └── ucd/ │ │ │ └── ucd.go │ │ ├── transform/ │ │ │ └── transform.go │ │ └── unicode/ │ │ ├── cldr/ │ │ │ ├── base.go │ │ │ ├── cldr.go │ │ │ ├── collate.go │ │ │ ├── decode.go │ │ │ ├── makexml.go │ │ │ ├── resolve.go │ │ │ ├── slice.go │ │ │ └── xml.go │ │ └── norm/ │ │ ├── composition.go │ │ ├── forminfo.go │ │ ├── input.go │ │ ├── iter.go │ │ ├── maketables.go │ │ ├── normalize.go │ │ ├── readwriter.go │ │ ├── tables.go │ │ ├── transform.go │ │ ├── trie.go │ │ └── triegen.go │ ├── google.golang.org/ │ │ └── appengine/ │ │ ├── LICENSE │ │ └── cloudsql/ │ │ ├── cloudsql.go │ │ ├── cloudsql_classic.go │ │ └── cloudsql_vm.go │ └── gopkg.in/ │ ├── asn1-ber.v1/ │ │ ├── .travis.yml │ │ ├── LICENSE │ │ ├── README.md │ │ ├── ber.go │ │ ├── content_int.go │ │ ├── header.go │ │ ├── identifier.go │ │ ├── length.go │ │ └── util.go │ ├── ldap.v3/ │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── CONTRIBUTING.md │ │ ├── LICENSE │ │ ├── Makefile │ │ ├── README.md │ │ ├── add.go │ │ ├── bind.go │ │ ├── client.go │ │ ├── compare.go │ │ ├── conn.go │ │ ├── control.go │ │ ├── debug.go │ │ ├── del.go │ │ ├── dn.go │ │ ├── doc.go │ │ ├── error.go │ │ ├── filter.go │ │ ├── ldap.go │ │ ├── moddn.go │ │ ├── modify.go │ │ ├── passwdmodify.go │ │ └── search.go │ └── yaml.v2/ │ ├── .travis.yml │ ├── LICENSE │ ├── LICENSE.libyaml │ ├── README.md │ ├── apic.go │ ├── decode.go │ ├── emitterc.go │ ├── encode.go │ ├── parserc.go │ ├── readerc.go │ ├── resolve.go │ ├── scannerc.go │ ├── sorter.go │ ├── writerc.go │ ├── yaml.go │ ├── yamlh.go │ └── yamlprivateh.go └── version.go
Showing preview only (4,268K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (55883 symbols across 542 files)
FILE: api/core/api.go
type API (line 44) | type API struct
method Serve (line 48) | func (r *API) Serve() error {
method status (line 56) | func (r *API) status(w api.ResponseWriter, req *rest.Request) {
method remove (line 69) | func (r *API) remove(w api.ResponseWriter, req *rest.Request) {
method announce (line 118) | func (r *API) announce(w api.ResponseWriter, req *rest.Request) {
type removeParam (line 92) | type removeParam struct
method UnmarshalJSON (line 96) | func (r *removeParam) UnmarshalJSON(data []byte) error {
type announceParam (line 134) | type announceParam struct
method UnmarshalJSON (line 139) | func (r *announceParam) UnmarshalJSON(data []byte) error {
FILE: api/response.go
type Status (line 42) | type Status
constant StatusOkay (line 45) | StatusOkay = 200
constant StatusInvalidParameter (line 47) | StatusInvalidParameter = 400
constant StatusIncorrectCredential (line 48) | StatusIncorrectCredential = 401
constant StatusUnknownSession (line 49) | StatusUnknownSession = 402
constant StatusPermissionDenied (line 50) | StatusPermissionDenied = 403
constant StatusDuplicated (line 51) | StatusDuplicated = 404
constant StatusNotFound (line 52) | StatusNotFound = 405
constant StatusBlockedAccount (line 53) | StatusBlockedAccount = 406
constant StatusBlockedHost (line 54) | StatusBlockedHost = 407
constant StatusInternalServerError (line 56) | StatusInternalServerError = 500
constant StatusServiceUnavailable (line 57) | StatusServiceUnavailable = 501
type Response (line 60) | type Response struct
function ResponseHandler (line 66) | func ResponseHandler(f func(ResponseWriter, *rest.Request)) func(rest.Re...
type ResponseWriter (line 73) | type ResponseWriter interface
type logWriter (line 84) | type logWriter struct
method Header (line 88) | func (r *logWriter) Header() http.Header {
method Write (line 92) | func (r *logWriter) Write(resp Response) {
method WriteHeader (line 107) | func (r *logWriter) WriteHeader(status int) {
FILE: api/server.go
type Server (line 42) | type Server struct
method validate (line 62) | func (r *Server) validate() error {
method Serve (line 73) | func (r *Server) Serve(routes ...*rest.Route) error {
type Observer (line 52) | type Observer interface
type Controller (line 56) | type Controller interface
FILE: api/ui/api.go
type API (line 46) | type API struct
method Serve (line 220) | func (r *API) Serve() error {
method announce (line 267) | func (r *API) announce(cidr, mac string) error {
type Database (line 54) | type Database interface
type LDAP (line 60) | type LDAP interface
type Transaction (line 64) | type Transaction interface
type Search (line 77) | type Search struct
method Validate (line 82) | func (r *Search) Validate() error {
function validateIP (line 103) | func validateIP(ip string) error {
function validateMAC (line 137) | func validateMAC(mac string) error {
type Sort (line 176) | type Sort struct
method Validate (line 181) | func (r *Sort) Validate() error {
type Column (line 192) | type Column
constant ColumnInvalid (line 195) | ColumnInvalid Column = iota
constant ColumnTime (line 196) | ColumnTime
constant ColumnIP (line 197) | ColumnIP
constant ColumnMAC (line 198) | ColumnMAC
constant ColumnPort (line 199) | ColumnPort
constant ColumnGroup (line 200) | ColumnGroup
constant ColumnDescription (line 201) | ColumnDescription
constant ColumnUser (line 202) | ColumnUser
constant ColumnLogType (line 203) | ColumnLogType
constant ColumnLogMethod (line 204) | ColumnLogMethod
type Order (line 207) | type Order
constant OrderInvalid (line 210) | OrderInvalid Order = iota
constant OrderAscending (line 211) | OrderAscending
constant OrderDescending (line 212) | OrderDescending
type Pagination (line 215) | type Pagination struct
FILE: api/ui/category.go
type CategoryTransaction (line 41) | type CategoryTransaction interface
type Category (line 51) | type Category struct
method MarshalJSON (line 57) | func (r *Category) MarshalJSON() ([]byte, error) {
method listCategory (line 69) | func (r *API) listCategory(w api.ResponseWriter, req *rest.Request) {
type listCategoryParam (line 96) | type listCategoryParam struct
method UnmarshalJSON (line 101) | func (r *listCategoryParam) UnmarshalJSON(data []byte) error {
method validate (line 114) | func (r *listCategoryParam) validate() error {
method addCategory (line 122) | func (r *API) addCategory(w api.ResponseWriter, req *rest.Request) {
type addCategoryParam (line 156) | type addCategoryParam struct
method UnmarshalJSON (line 161) | func (r *addCategoryParam) UnmarshalJSON(data []byte) error {
method validate (line 174) | func (r *addCategoryParam) validate() error {
method updateCategory (line 185) | func (r *API) updateCategory(w api.ResponseWriter, req *rest.Request) {
type updateCategoryParam (line 223) | type updateCategoryParam struct
method UnmarshalJSON (line 229) | func (r *updateCategoryParam) UnmarshalJSON(data []byte) error {
method validate (line 243) | func (r *updateCategoryParam) validate() error {
method removeCategory (line 257) | func (r *API) removeCategory(w api.ResponseWriter, req *rest.Request) {
type removeCategoryParam (line 290) | type removeCategoryParam struct
method UnmarshalJSON (line 295) | func (r *removeCategoryParam) UnmarshalJSON(data []byte) error {
method validate (line 308) | func (r *removeCategoryParam) validate() error {
FILE: api/ui/component.go
type ComponentTransaction (line 41) | type ComponentTransaction interface
type Component (line 51) | type Component struct
method MarshalJSON (line 58) | func (r *Component) MarshalJSON() ([]byte, error) {
method listComponent (line 72) | func (r *API) listComponent(w api.ResponseWriter, req *rest.Request) {
type listComponentParam (line 99) | type listComponentParam struct
method UnmarshalJSON (line 105) | func (r *listComponentParam) UnmarshalJSON(data []byte) error {
method validate (line 119) | func (r *listComponentParam) validate() error {
method addComponent (line 130) | func (r *API) addComponent(w api.ResponseWriter, req *rest.Request) {
type addComponentParam (line 164) | type addComponentParam struct
method UnmarshalJSON (line 170) | func (r *addComponentParam) UnmarshalJSON(data []byte) error {
method validate (line 184) | func (r *addComponentParam) validate() error {
method updateComponent (line 198) | func (r *API) updateComponent(w api.ResponseWriter, req *rest.Request) {
type updateComponentParam (line 236) | type updateComponentParam struct
method UnmarshalJSON (line 242) | func (r *updateComponentParam) UnmarshalJSON(data []byte) error {
method validate (line 256) | func (r *updateComponentParam) validate() error {
method removeComponent (line 270) | func (r *API) removeComponent(w api.ResponseWriter, req *rest.Request) {
type removeComponentParam (line 303) | type removeComponentParam struct
method UnmarshalJSON (line 308) | func (r *removeComponentParam) UnmarshalJSON(data []byte) error {
method validate (line 321) | func (r *removeComponentParam) validate() error {
FILE: api/ui/group.go
type GroupTransaction (line 41) | type GroupTransaction interface
type Group (line 51) | type Group struct
method MarshalJSON (line 57) | func (r *Group) MarshalJSON() ([]byte, error) {
method listGroup (line 69) | func (r *API) listGroup(w api.ResponseWriter, req *rest.Request) {
type listGroupParam (line 96) | type listGroupParam struct
method UnmarshalJSON (line 101) | func (r *listGroupParam) UnmarshalJSON(data []byte) error {
method validate (line 114) | func (r *listGroupParam) validate() error {
method addGroup (line 122) | func (r *API) addGroup(w api.ResponseWriter, req *rest.Request) {
type addGroupParam (line 156) | type addGroupParam struct
method UnmarshalJSON (line 161) | func (r *addGroupParam) UnmarshalJSON(data []byte) error {
method validate (line 174) | func (r *addGroupParam) validate() error {
method updateGroup (line 185) | func (r *API) updateGroup(w api.ResponseWriter, req *rest.Request) {
type updateGroupParam (line 223) | type updateGroupParam struct
method UnmarshalJSON (line 229) | func (r *updateGroupParam) UnmarshalJSON(data []byte) error {
method validate (line 243) | func (r *updateGroupParam) validate() error {
method removeGroup (line 257) | func (r *API) removeGroup(w api.ResponseWriter, req *rest.Request) {
type removeGroupParam (line 290) | type removeGroupParam struct
method UnmarshalJSON (line 295) | func (r *removeGroupParam) UnmarshalJSON(data []byte) error {
method validate (line 308) | func (r *removeGroupParam) validate() error {
FILE: api/ui/host.go
type HostTransaction (line 49) | type HostTransaction interface
type Host (line 65) | type Host struct
method MarshalJSON (line 78) | func (r *Host) MarshalJSON() ([]byte, error) {
type Spec (line 104) | type Spec struct
method listHost (line 110) | func (r *API) listHost(w api.ResponseWriter, req *rest.Request) {
type listHostParam (line 137) | type listHostParam struct
method UnmarshalJSON (line 144) | func (r *listHostParam) UnmarshalJSON(data []byte) error {
method validate (line 159) | func (r *listHostParam) validate() error {
method getHost (line 179) | func (r *API) getHost(w api.ResponseWriter, req *rest.Request) {
type getHostParam (line 211) | type getHostParam struct
method UnmarshalJSON (line 216) | func (r *getHostParam) UnmarshalJSON(data []byte) error {
method validate (line 229) | func (r *getHostParam) validate() error {
method addHost (line 240) | func (r *API) addHost(w api.ResponseWriter, req *rest.Request) {
type addHostParam (line 291) | type addHostParam struct
method UnmarshalJSON (line 300) | func (r *addHostParam) UnmarshalJSON(data []byte) error {
type SpecParam (line 350) | type SpecParam struct
method Validate (line 355) | func (r *SpecParam) Validate() error {
method updateHost (line 366) | func (r *API) updateHost(w api.ResponseWriter, req *rest.Request) {
type updateHostParam (line 440) | type updateHostParam struct
method UnmarshalJSON (line 450) | func (r *updateHostParam) UnmarshalJSON(data []byte) error {
method activateHost (line 506) | func (r *API) activateHost(w api.ResponseWriter, req *rest.Request) {
type activateHostParam (line 544) | type activateHostParam struct
method UnmarshalJSON (line 549) | func (r *activateHostParam) UnmarshalJSON(data []byte) error {
method validate (line 562) | func (r *activateHostParam) validate() error {
method deactivateHost (line 573) | func (r *API) deactivateHost(w api.ResponseWriter, req *rest.Request) {
type deactivateHostParam (line 619) | type deactivateHostParam struct
method UnmarshalJSON (line 624) | func (r *deactivateHostParam) UnmarshalJSON(data []byte) error {
method validate (line 637) | func (r *deactivateHostParam) validate() error {
method removeHost (line 648) | func (r *API) removeHost(w api.ResponseWriter, req *rest.Request) {
type removeHostParam (line 686) | type removeHostParam struct
method UnmarshalJSON (line 691) | func (r *removeHostParam) UnmarshalJSON(data []byte) error {
method validate (line 704) | func (r *removeHostParam) validate() error {
FILE: api/ui/ip.go
type IPTransaction (line 39) | type IPTransaction interface
type IP (line 43) | type IP struct
method listIP (line 55) | func (r *API) listIP(w api.ResponseWriter, req *rest.Request) {
type listIPParam (line 82) | type listIPParam struct
method UnmarshalJSON (line 87) | func (r *listIPParam) UnmarshalJSON(data []byte) error {
method validate (line 100) | func (r *listIPParam) validate() error {
FILE: api/ui/log.go
type LogType (line 40) | type LogType
method Validate (line 53) | func (r LogType) Validate() error {
constant LogTypeUser (line 43) | LogTypeUser LogType = "USER"
constant LogTypeGroup (line 44) | LogTypeGroup LogType = "GROUP"
constant LogTypeSwitch (line 45) | LogTypeSwitch LogType = "SWITCH"
constant LogTypeNetwork (line 46) | LogTypeNetwork LogType = "NETWORK"
constant LogTypeHost (line 47) | LogTypeHost LogType = "HOST"
constant LogTypeVIP (line 48) | LogTypeVIP LogType = "VIP"
constant LogTypeCategory (line 49) | LogTypeCategory LogType = "CATEGORY"
constant LogTypeComponent (line 50) | LogTypeComponent LogType = "COMPONENT"
type LogMethod (line 62) | type LogMethod
method Validate (line 70) | func (r LogMethod) Validate() error {
constant LogMethodAdd (line 65) | LogMethodAdd LogMethod = "ADD"
constant LogMethodUpdate (line 66) | LogMethodUpdate LogMethod = "UPDATE"
constant LogMethodRemove (line 67) | LogMethodRemove LogMethod = "REMOVE"
type LogTransaction (line 78) | type LogTransaction interface
type Log (line 83) | type Log struct
method MarshalJSON (line 92) | func (r *Log) MarshalJSON() ([]byte, error) {
method listLog (line 110) | func (r *API) listLog(w api.ResponseWriter, req *rest.Request) {
type listLogParam (line 137) | type listLogParam struct
method UnmarshalJSON (line 143) | func (r *listLogParam) UnmarshalJSON(data []byte) error {
method validate (line 157) | func (r *listLogParam) validate() error {
FILE: api/ui/network.go
type NetworkTransaction (line 41) | type NetworkTransaction interface
type Network (line 49) | type Network struct
method listNetwork (line 56) | func (r *API) listNetwork(w api.ResponseWriter, req *rest.Request) {
type listNetworkParam (line 83) | type listNetworkParam struct
method UnmarshalJSON (line 89) | func (r *listNetworkParam) UnmarshalJSON(data []byte) error {
method validate (line 103) | func (r *listNetworkParam) validate() error {
method addNetwork (line 116) | func (r *API) addNetwork(w api.ResponseWriter, req *rest.Request) {
type addNetworkParam (line 150) | type addNetworkParam struct
method UnmarshalJSON (line 157) | func (r *addNetworkParam) UnmarshalJSON(data []byte) error {
function validateGateway (line 194) | func validateGateway(n net.IPNet, g net.IP) error {
method removeNetwork (line 216) | func (r *API) removeNetwork(w api.ResponseWriter, req *rest.Request) {
type removeNetworkParam (line 257) | type removeNetworkParam struct
method UnmarshalJSON (line 262) | func (r *removeNetworkParam) UnmarshalJSON(data []byte) error {
method validate (line 275) | func (r *removeNetworkParam) validate() error {
FILE: api/ui/session.go
type session (line 40) | type session struct
method Add (line 57) | func (r *session) Add(v interface{}) (id string) {
method Get (line 77) | func (r *session) Get(id string) (interface{}, bool) {
method Remove (line 95) | func (r *session) Remove(id string) bool {
function newSession (line 45) | func newSession(size int, timeout time.Duration) *session {
type sessionEntry (line 65) | type sessionEntry struct
function hash (line 70) | func hash(value string) string {
FILE: api/ui/switch.go
type SwitchTransaction (line 43) | type SwitchTransaction interface
type Switch (line 50) | type Switch struct
method MarshalJSON (line 59) | func (r *Switch) MarshalJSON() ([]byte, error) {
function hexDPID (line 83) | func hexDPID(dpid uint64) string {
method listSwitch (line 89) | func (r *API) listSwitch(w api.ResponseWriter, req *rest.Request) {
type listSwitchParam (line 116) | type listSwitchParam struct
method UnmarshalJSON (line 121) | func (r *listSwitchParam) UnmarshalJSON(data []byte) error {
method validate (line 134) | func (r *listSwitchParam) validate() error {
method addSwitch (line 145) | func (r *API) addSwitch(w api.ResponseWriter, req *rest.Request) {
type addSwitchParam (line 179) | type addSwitchParam struct
method UnmarshalJSON (line 188) | func (r *addSwitchParam) UnmarshalJSON(data []byte) error {
method removeSwitch (line 242) | func (r *API) removeSwitch(w api.ResponseWriter, req *rest.Request) {
type removeSwitchParam (line 283) | type removeSwitchParam struct
method UnmarshalJSON (line 288) | func (r *removeSwitchParam) UnmarshalJSON(data []byte) error {
method validate (line 301) | func (r *removeSwitchParam) validate() error {
FILE: api/ui/user.go
type UserTransaction (line 42) | type UserTransaction interface
type User (line 51) | type User struct
method MarshalJSON (line 60) | func (r *User) MarshalJSON() ([]byte, error) {
method login (line 76) | func (r *API) login(w api.ResponseWriter, req *rest.Request) {
type loginParam (line 141) | type loginParam struct
method UnmarshalJSON (line 147) | func (r *loginParam) UnmarshalJSON(data []byte) error {
method validate (line 161) | func (r *loginParam) validate() error {
method logout (line 175) | func (r *API) logout(w api.ResponseWriter, req *rest.Request) {
type logoutParam (line 192) | type logoutParam struct
method UnmarshalJSON (line 196) | func (r *logoutParam) UnmarshalJSON(data []byte) error {
method validate (line 208) | func (r *logoutParam) validate() error {
method listUser (line 216) | func (r *API) listUser(w api.ResponseWriter, req *rest.Request) {
type listUserParam (line 248) | type listUserParam struct
method UnmarshalJSON (line 253) | func (r *listUserParam) UnmarshalJSON(data []byte) error {
method validate (line 266) | func (r *listUserParam) validate() error {
method addUser (line 277) | func (r *API) addUser(w api.ResponseWriter, req *rest.Request) {
type addUserParam (line 330) | type addUserParam struct
method UnmarshalJSON (line 335) | func (r *addUserParam) UnmarshalJSON(data []byte) error {
method validate (line 348) | func (r *addUserParam) validate() error {
function generateOTPKey (line 359) | func generateOTPKey(account string) (*otp.Key, error) {
method updateUser (line 366) | func (r *API) updateUser(w api.ResponseWriter, req *rest.Request) {
type updateUserParam (line 403) | type updateUserParam struct
method UnmarshalJSON (line 410) | func (r *updateUserParam) UnmarshalJSON(data []byte) error {
method validate (line 425) | func (r *updateUserParam) validate() error {
method resetOTP (line 439) | func (r *API) resetOTP(w api.ResponseWriter, req *rest.Request) {
type resetOTPParam (line 481) | type resetOTPParam struct
method UnmarshalJSON (line 486) | func (r *resetOTPParam) UnmarshalJSON(data []byte) error {
method validate (line 499) | func (r *resetOTPParam) validate() error {
FILE: api/ui/vip.go
type VIPTransaction (line 41) | type VIPTransaction interface
type VIP (line 50) | type VIP struct
method listVIP (line 58) | func (r *API) listVIP(w api.ResponseWriter, req *rest.Request) {
type listVIPParam (line 85) | type listVIPParam struct
method UnmarshalJSON (line 90) | func (r *listVIPParam) UnmarshalJSON(data []byte) error {
method validate (line 103) | func (r *listVIPParam) validate() error {
method addVIP (line 114) | func (r *API) addVIP(w api.ResponseWriter, req *rest.Request) {
type addVIPParam (line 153) | type addVIPParam struct
method UnmarshalJSON (line 161) | func (r *addVIPParam) UnmarshalJSON(data []byte) error {
method validate (line 177) | func (r *addVIPParam) validate() error {
method removeVIP (line 197) | func (r *API) removeVIP(w api.ResponseWriter, req *rest.Request) {
type removeVIPParam (line 235) | type removeVIPParam struct
method UnmarshalJSON (line 240) | func (r *removeVIPParam) UnmarshalJSON(data []byte) error {
method validate (line 253) | func (r *removeVIPParam) validate() error {
method toggleVIP (line 264) | func (r *API) toggleVIP(w api.ResponseWriter, req *rest.Request) {
type toggleVIPParam (line 302) | type toggleVIPParam struct
method UnmarshalJSON (line 307) | func (r *toggleVIPParam) UnmarshalJSON(data []byte) error {
method validate (line 320) | func (r *toggleVIPParam) validate() error {
FILE: cmd/cherry/main.go
constant programName (line 52) | programName = "cherry"
constant programVersion (line 53) | programVersion = cherry.Version
constant defaultLogLevel (line 54) | defaultLogLevel = logging.INFO
function main (line 64) | func main() {
function initConfig (line 97) | func initConfig() {
function validateConfig (line 121) | func validateConfig() error {
function initElectionObserver (line 142) | func initElectionObserver(ctx context.Context, db *database.MySQL) *elec...
function initAPIServer (line 154) | func initAPIServer(observer *election.Observer, controller *network.Cont...
function initSignalHandler (line 172) | func initSignalHandler(controller *network.Controller, manager *northbou...
function initLog (line 198) | func initLog(level logging.Level) error {
function getLogLevel (line 213) | func getLogLevel(level string) logging.Level {
function listen (line 224) | func listen(ctx context.Context, port int, controller *network.Controlle...
function createAppManager (line 285) | func createAppManager(db *database.MySQL) (*northbound.Manager, error) {
function parseApplications (line 304) | func parseApplications() ([]string, error) {
FILE: cmd/walnut/main.go
constant programName (line 52) | programName = "walnut"
constant programVersion (line 53) | programVersion = cherry.Version
constant defaultLogLevel (line 54) | defaultLogLevel = logging.INFO
function init (line 66) | func init() {
function main (line 71) | func main() {
function parseCmdLines (line 81) | func parseCmdLines() {
function initConfig (line 93) | func initConfig() {
function validateConfig (line 119) | func validateConfig() error {
function initLog (line 124) | func initLog() {
function getLogLevel (line 149) | func getLogLevel() logging.Level {
function initDatabase (line 160) | func initDatabase() *database.MySQL {
function initCoreSDK (line 169) | func initCoreSDK() *coreSDK {
function initLDAPClient (line 178) | func initLDAPClient() *ldap.Client {
function initAPIServer (line 182) | func initAPIServer() {
function waitSignal (line 202) | func waitSignal() {
FILE: cmd/walnut/sdk.go
type coreSDK (line 25) | type coreSDK struct
method Announce (line 49) | func (r *coreSDK) Announce(ip net.IP, mac net.HardwareAddr) error {
method RemoveFlows (line 61) | func (r *coreSDK) RemoveFlows() error {
method RemoveFlowsByMAC (line 65) | func (r *coreSDK) RemoveFlowsByMAC(mac net.HardwareAddr) error {
method IsMaster (line 73) | func (r *coreSDK) IsMaster() bool {
method call (line 84) | func (r *coreSDK) call(method, command string, param interface{}, resu...
function newCoreSDK (line 30) | func newCoreSDK(baseURL string) (*coreSDK, error) {
FILE: database/mysql.go
constant maxDeadlockRetry (line 51) | maxDeadlockRetry = 5
constant deadlockErrCode (line 53) | deadlockErrCode uint16 = 1213
constant duplicatedErrCode (line 54) | duplicatedErrCode uint16 = 1062
constant foreignkeyErrCode (line 55) | foreignkeyErrCode uint16 = 1451
constant clusterDialerNetwork (line 57) | clusterDialerNetwork = "cluster"
type MySQL (line 67) | type MySQL struct
method query (line 165) | func (r *MySQL) query(f func(*sql.Tx) error) error {
method MAC (line 215) | func (r *MySQL) MAC(ip net.IP) (mac net.HardwareAddr, ok bool, err err...
method Location (line 271) | func (r *MySQL) Location(mac net.HardwareAddr) (dpid string, port uint...
method TogglePortVIP (line 316) | func (r *MySQL) TogglePortVIP(swDPID uint64, portNum uint16) (result [...
method ToggleDeviceVIP (line 347) | func (r *MySQL) ToggleDeviceVIP(swDPID uint64) (result []virtualip.Add...
method GetUndiscoveredHosts (line 511) | func (r *MySQL) GetUndiscoveredHosts(expiration time.Duration) (result...
method UpdateHostLocation (line 562) | func (r *MySQL) UpdateHostLocation(mac net.HardwareAddr, ip net.IP, sw...
method ResetHostLocationsByPort (line 642) | func (r *MySQL) ResetHostLocationsByPort(swDPID uint64, portNum uint16...
method ResetHostLocationsByDevice (line 662) | func (r *MySQL) ResetHostLocationsByDevice(swDPID uint64) error {
method Elect (line 684) | func (r *MySQL) Elect(uid string, expiration time.Duration) (elected b...
method MACAddrs (line 703) | func (r *MySQL) MACAddrs() (result []net.HardwareAddr, err error) {
method RenewARPTable (line 736) | func (r *MySQL) RenewARPTable() error {
method GetARPTable (line 816) | func (r *MySQL) GetARPTable() (result []announcer.ARPTableEntry, err e...
method DHCP (line 894) | func (r *MySQL) DHCP(mac net.HardwareAddr) (conf *dhcp.NetConfig, err ...
method Exec (line 936) | func (r *MySQL) Exec(f func(ui.Transaction) error) error {
function NewMySQL (line 72) | func NewMySQL() (*MySQL, error) {
function validateClusterAddr (line 100) | func validateClusterAddr(addr string) error {
function clusterDialer (line 121) | func clusterDialer(addr string) (net.Conn, error) {
function isDeadlock (line 138) | func isDeadlock(err error) bool {
function isDuplicated (line 147) | func isDuplicated(err error) bool {
function isForeignkeyErr (line 156) | func isForeignkeyErr(err error) bool {
function caller (line 201) | func caller() string {
function portID (line 374) | func portID(tx *sql.Tx, swDPID uint64, portNum uint16) (uint64, error) {
type vip (line 398) | type vip struct
function getPortVIPs (line 405) | func getPortVIPs(tx *sql.Tx, portID uint64) (result []vip, err error) {
function getDeviceVIPs (line 437) | func getDeviceVIPs(tx *sql.Tx, swDPID uint64) (result []vip, err error) {
function swapVIPHosts (line 471) | func swapVIPHosts(tx *sql.Tx, v vip) error {
function hostMAC (line 486) | func hostMAC(tx *sql.Tx, hostID uint64) (net.HardwareAddr, error) {
function getHostID (line 593) | func getHostID(tx *sql.Tx, mac net.HardwareAddr, ip net.IP) (hostID uint...
function updateLocation (line 618) | func updateLocation(tx *sql.Tx, hostID, portID uint64) (updated bool, er...
type arpEntry (line 759) | type arpEntry struct
function getHostARPEntries (line 764) | func getHostARPEntries(tx *sql.Tx) (result []arpEntry, err error) {
function getVIPARPEntries (line 790) | func getVIPARPEntries(tx *sql.Tx) (result []arpEntry, err error) {
function updateARPTableEntryByHost (line 851) | func updateARPTableEntryByHost(tx *sql.Tx, id uint64, invalidate bool) e...
function updateARPTableEntryByVIP (line 867) | func updateARPTableEntryByVIP(tx *sql.Tx, id uint64, invalidate bool) er...
function updateARPTableEntry (line 884) | func updateARPTableEntry(tx *sql.Tx, ip, mac string) error {
type uiTx (line 972) | type uiTx struct
method Groups (line 976) | func (r *uiTx) Groups(pagination ui.Pagination) (group []*ui.Group, er...
method AddGroup (line 1005) | func (r *uiTx) AddGroup(requesterID uint64, name string) (group *ui.Gr...
method UpdateGroup (line 1044) | func (r *uiTx) UpdateGroup(requesterID, groupID uint64, name string) (...
method RemoveGroup (line 1074) | func (r *uiTx) RemoveGroup(requesterID, groupID uint64) (group *ui.Gro...
method Hosts (line 1098) | func (r *uiTx) Hosts(search *ui.Search, sort ui.Sort, pagination ui.Pa...
method Host (line 1253) | func (r *uiTx) Host(id uint64) (host *ui.Host, err error) {
method AddHost (line 1347) | func (r *uiTx) AddHost(requesterID, ipID uint64, groupID *uint64, mac ...
method UpdateHost (line 1438) | func (r *uiTx) UpdateHost(requesterID, hostID uint64, ipID, groupID *u...
method ActivateHost (line 1499) | func (r *uiTx) ActivateHost(requesterID, hostID uint64) (host *ui.Host...
method DeactivateHost (line 1530) | func (r *uiTx) DeactivateHost(requesterID, hostID uint64) (host *ui.Ho...
method CountVIPByHostID (line 1561) | func (r *uiTx) CountVIPByHostID(id uint64) (count uint64, err error) {
method RemoveHost (line 1570) | func (r *uiTx) RemoveHost(requesterID, hostID uint64) (host *ui.Host, ...
method IPAddrs (line 1604) | func (r *uiTx) IPAddrs(networkID uint64) (address []*ui.IP, err error) {
method Networks (line 1653) | func (r *uiTx) Networks(address *string, pagination ui.Pagination) (ne...
method AddNetwork (line 1686) | func (r *uiTx) AddNetwork(requesterID uint64, addr net.IP, mask net.IP...
method RemoveNetwork (line 1777) | func (r *uiTx) RemoveNetwork(requesterID, netID uint64) (network *ui.N...
method Switches (line 1801) | func (r *uiTx) Switches(pagination ui.Pagination) (sw []*ui.Switch, er...
method AddSwitch (line 1828) | func (r *uiTx) AddSwitch(requesterID, dpid uint64, nPorts, firstPort, ...
method RemoveSwitch (line 1897) | func (r *uiTx) RemoveSwitch(requesterID, swID uint64) (sw *ui.Switch, ...
method User (line 1921) | func (r *uiTx) User(name string) (user *ui.User, err error) {
method Users (line 1937) | func (r *uiTx) Users(pagination ui.Pagination) (user []*ui.User, err e...
method AddUser (line 1964) | func (r *uiTx) AddUser(requesterID uint64, name, key string) (user *ui...
method UpdateUser (line 2005) | func (r *uiTx) UpdateUser(requesterID, userID uint64, enabled, admin *...
method ResetOTPKey (line 2047) | func (r *uiTx) ResetOTPKey(name, key string) (ok bool, err error) {
method VIPs (line 2064) | func (r *uiTx) VIPs(pagination ui.Pagination) (vip []*ui.VIP, err erro...
method getVIPs (line 2108) | func (r *uiTx) getVIPs(pagination ui.Pagination) (vip []registeredVIP,...
method AddVIP (line 2137) | func (r *uiTx) AddVIP(requesterID, ipID, activeID, standbyID uint64, d...
method RemoveVIP (line 2242) | func (r *uiTx) RemoveVIP(requesterID, vipID uint64) (vip *ui.VIP, err ...
method ToggleVIP (line 2266) | func (r *uiTx) ToggleVIP(requesterID, vipID uint64) (res *ui.VIP, err ...
method QueryLog (line 2302) | func (r *uiTx) QueryLog(search *ui.Search, pagination ui.Pagination) (...
method log (line 2396) | func (r *uiTx) log(userID uint64, t logType, m logMethod, data interfa...
method Categories (line 2413) | func (r *uiTx) Categories(pagination ui.Pagination) (category []*ui.Ca...
method AddCategory (line 2442) | func (r *uiTx) AddCategory(requesterID uint64, name string) (category ...
method UpdateCategory (line 2481) | func (r *uiTx) UpdateCategory(requesterID, categoryID uint64, name str...
method RemoveCategory (line 2512) | func (r *uiTx) RemoveCategory(requesterID, categoryID uint64) (categor...
method Components (line 2536) | func (r *uiTx) Components(categoryID uint64, pagination ui.Pagination)...
method AddComponent (line 2568) | func (r *uiTx) AddComponent(requesterID, categoryID uint64, name strin...
method UpdateComponent (line 2608) | func (r *uiTx) UpdateComponent(requesterID, componentID uint64, name s...
method RemoveComponent (line 2639) | func (r *uiTx) RemoveComponent(requesterID, componentID uint64) (compo...
function getGroup (line 1031) | func getGroup(tx *sql.Tx, id uint64) (*ui.Group, error) {
function buildHostsQuery (line 1142) | func buildHostsQuery(search *ui.Search, sort ui.Sort, pagination ui.Pagi...
function rangeIP (line 1218) | func rangeIP(ip string) (start, end uint32) {
function convertIPToInt (line 1231) | func convertIPToInt(ip net.IP) uint32 {
function rangeMAC (line 1240) | func rangeMAC(mac string) (start, end string) {
function getHost (line 1266) | func getHost(tx *sql.Tx, id uint64) (*host, error) {
type host (line 1313) | type host struct
method convert (line 1332) | func (r *host) convert() *ui.Host {
function addNewHost (line 1363) | func addNewHost(tx *sql.Tx, ipID uint64, groupID *uint64, mac net.Hardwa...
function isAvailableIP (line 1402) | func isAvailableIP(tx *sql.Tx, id uint64) (bool, error) {
function encodeMAC (line 1421) | func encodeMAC(mac net.HardwareAddr) string {
function decodeMAC (line 1426) | func decodeMAC(s string) (net.HardwareAddr, error) {
function updateHost (line 1470) | func updateHost(tx *sql.Tx, old *host, ipID, groupID *uint64, mac net.Ha...
function removeHost (line 1591) | func removeHost(tx *sql.Tx, id uint64) error {
function addNetwork (line 1711) | func addNetwork(tx *sql.Tx, addr net.IP, mask net.IPMask, gateway net.IP...
function addIPAddrs (line 1726) | func addIPAddrs(tx *sql.Tx, netID uint64, addr net.IP, mask net.IPMask) ...
function calculateIP (line 1753) | func calculateIP(network net.IP, n uint32) net.IP {
function getNetwork (line 1764) | func getNetwork(tx *sql.Tx, id uint64) (*ui.Network, error) {
function addSwitch (line 1854) | func addSwitch(tx *sql.Tx, dpid uint64, nPorts, firstPort, firstPrintedP...
function addPorts (line 1868) | func addPorts(tx *sql.Tx, swID uint64, firstPort, n_ports uint16) error {
function getSwitch (line 1884) | func getSwitch(tx *sql.Tx, id uint64) (*ui.Switch, error) {
function getUser (line 1992) | func getUser(tx *sql.Tx, id uint64) (*ui.User, error) {
type registeredVIP (line 2100) | type registeredVIP struct
function addNewVIP (line 2163) | func addNewVIP(tx *sql.Tx, ipID, activeID, standbyID uint64, desc string...
function isEnabledHost (line 2197) | func isEnabledHost(tx *sql.Tx, id uint64) (enabled bool, err error) {
function getVIP (line 2206) | func getVIP(tx *sql.Tx, id uint64) (vip *ui.VIP, err error) {
function buildLogsQuery (line 2325) | func buildLogsQuery(search *ui.Search, pagination ui.Pagination) (qry st...
type logType (line 2357) | type logType
method validate (line 2371) | func (r logType) validate() error {
constant logTypeInvalid (line 2360) | logTypeInvalid logType = iota
constant logTypeUser (line 2361) | logTypeUser
constant logTypeGroup (line 2362) | logTypeGroup
constant logTypeSwitch (line 2363) | logTypeSwitch
constant logTypeNetwork (line 2364) | logTypeNetwork
constant logTypeHost (line 2365) | logTypeHost
constant logTypeVIP (line 2366) | logTypeVIP
constant logTypeCategory (line 2367) | logTypeCategory
constant logTypeComponent (line 2368) | logTypeComponent
type logMethod (line 2379) | type logMethod
method validate (line 2388) | func (r logMethod) validate() error {
constant logMethodInvalid (line 2382) | logMethodInvalid logMethod = iota
constant logMethodAdd (line 2383) | logMethodAdd
constant logMethodUpdate (line 2384) | logMethodUpdate
constant logMethodRemove (line 2385) | logMethodRemove
function getCategory (line 2468) | func getCategory(tx *sql.Tx, id uint64) (category *ui.Category, err erro...
function getComponent (line 2594) | func getComponent(tx *sql.Tx, id uint64) (component *ui.Component, err e...
function getSpec (line 2663) | func getSpec(tx *sql.Tx, hostID uint64) (spec []*ui.Spec, err error) {
function addSpec (line 2694) | func addSpec(tx *sql.Tx, hostID, componentID uint64, count uint16) error {
FILE: database/mysql_schema.sql
type `user` (line 24) | CREATE TABLE IF NOT EXISTS `user` (
type `group` (line 42) | CREATE TABLE IF NOT EXISTS `group` (
type `log` (line 57) | CREATE TABLE IF NOT EXISTS `log` (
type `category` (line 77) | CREATE TABLE IF NOT EXISTS `category` (
type `component` (line 92) | CREATE TABLE IF NOT EXISTS `component` (
type `spec` (line 109) | CREATE TABLE IF NOT EXISTS `spec` (
type `arp` (line 127) | CREATE TABLE IF NOT EXISTS `arp` (
type `master_election` (line 142) | CREATE TABLE IF NOT EXISTS `master_election` (
type `acl` (line 156) | CREATE TABLE IF NOT EXISTS `acl` (
type `network` (line 171) | CREATE TABLE IF NOT EXISTS `network` (
type `switch` (line 187) | CREATE TABLE IF NOT EXISTS `switch` (
type `port` (line 206) | CREATE TABLE IF NOT EXISTS `port` (
type `ip` (line 222) | CREATE TABLE IF NOT EXISTS `ip` (
type `host` (line 241) | CREATE TABLE IF NOT EXISTS `host` (
type `vip` (line 318) | CREATE TABLE IF NOT EXISTS `vip` (
FILE: database/random.go
type randomSource (line 30) | type randomSource struct
method Int63 (line 35) | func (r *randomSource) Int63() (n int64) {
method Seed (line 42) | func (r *randomSource) Seed(seed int64) {
FILE: election/election.go
constant interval (line 41) | interval = 1 * time.Second
type Observer (line 44) | type Observer struct
method Run (line 72) | func (r *Observer) Run(ctx context.Context) error {
method IsMaster (line 107) | func (r *Observer) IsMaster() bool {
method setMaster (line 111) | func (r *Observer) setMaster(value bool) {
method getMaster (line 118) | func (r *Observer) getMaster() bool {
type Database (line 52) | type Database interface
function New (line 59) | func New(db Database) *Observer {
function generateRandomUID (line 66) | func generateRandomUID() string {
FILE: graph/graph.go
type Vertex (line 41) | type Vertex interface
type Point (line 46) | type Point interface
type Edge (line 52) | type Edge interface
type edge (line 58) | type edge struct
type vertex (line 64) | type vertex struct
type Graph (line 69) | type Graph struct
method String (line 84) | func (r *Graph) String() string {
method AddVertex (line 98) | func (r *Graph) AddVertex(v Vertex) {
method removeEdge (line 118) | func (r *Graph) removeEdge(e Edge) {
method RemoveVertex (line 133) | func (r *Graph) RemoveVertex(v Vertex) {
method AddEdge (line 152) | func (r *Graph) AddEdge(e Edge) (added bool, err error) {
method RemoveEdge (line 190) | func (r *Graph) RemoveEdge(p Point) {
method IsEdge (line 204) | func (r *Graph) IsEdge(p Point) bool {
method IsEnabledPoint (line 218) | func (r *Graph) IsEnabledPoint(p Point) bool {
method pickRootVertex (line 253) | func (r *Graph) pickRootVertex() Vertex {
method resetEdges (line 265) | func (r *Graph) resetEdges() *list.List {
method pickValidVertexies (line 282) | func (r *Graph) pickValidVertexies() []Vertex {
method makeClusters (line 294) | func (r *Graph) makeClusters() map[string]*list.List {
method calculateMST (line 318) | func (r *Graph) calculateMST() {
method FindPath (line 388) | func (r *Graph) FindPath(src, dst Vertex) []Path {
method RemoveStaleEdges (line 462) | func (r *Graph) RemoveStaleEdges(expiration time.Duration) (removed bo...
function New (line 76) | func New() *Graph {
type sortedEdge (line 235) | type sortedEdge
method Len (line 237) | func (r sortedEdge) Len() int {
method Less (line 241) | func (r sortedEdge) Less(i, j int) bool {
method Swap (line 249) | func (r sortedEdge) Swap(i, j int) {
function mergeCluster (line 305) | func mergeCluster(clusters map[string]*list.List, l1, l2 *list.List) {
type queue (line 359) | type queue struct
method enqueue (line 367) | func (r *queue) enqueue(v interface{}) {
method dequeue (line 371) | func (r *queue) dequeue() interface{} {
method length (line 379) | func (r *queue) length() int {
function newQueue (line 363) | func newQueue() *queue {
type Path (line 383) | type Path struct
function reverse (line 448) | func reverse(data []Path) []Path {
FILE: graph/graph_test.go
type node (line 29) | type node struct
method ID (line 33) | func (r node) ID() string {
type point (line 37) | type point struct
method ID (line 42) | func (r point) ID() string {
method Vertex (line 46) | func (r point) Vertex() Vertex {
type link (line 50) | type link struct
method ID (line 55) | func (r link) ID() string {
method Points (line 59) | func (r link) Points() [2]Point {
method Weight (line 63) | func (r link) Weight() float64 {
function printEnabledEdges (line 67) | func printEnabledEdges(g *Graph) (int, float64) {
function TestInvalidMST (line 82) | func TestInvalidMST(t *testing.T) {
function TestRemoveVertex (line 100) | func TestRemoveVertex(t *testing.T) {
function TestRemoveEdges (line 127) | func TestRemoveEdges(t *testing.T) {
function TestDuplicatedEdges (line 172) | func TestDuplicatedEdges(t *testing.T) {
function TestMST0 (line 194) | func TestMST0(t *testing.T) {
function TestMST1 (line 256) | func TestMST1(t *testing.T) {
function TestMST2 (line 306) | func TestMST2(t *testing.T) {
function TestMST3 (line 391) | func TestMST3(t *testing.T) {
function TestMST4 (line 486) | func TestMST4(t *testing.T) {
FILE: ldap/client.go
type Client (line 37) | type Client struct
method Auth (line 58) | func (r *Client) Auth(username, password string) (ok bool, err error) {
method bindAdmin (line 91) | func (r *Client) bindAdmin(conn *ldap.Conn) error {
method getDN (line 96) | func (r *Client) getDN(conn *ldap.Conn, username string) (dn string, e...
function New (line 46) | func New(config *viper.Viper, maxConn int) *Client {
FILE: ldap/conn.go
method acquireConn (line 34) | func (r *Client) acquireConn() (conn *ldap.Conn, err error) {
method createConn (line 45) | func (r *Client) createConn() (*ldap.Conn, error) {
method releaseConn (line 61) | func (r *Client) releaseConn(conn *ldap.Conn) {
FILE: log/syslog.go
type syslog (line 33) | type syslog struct
method Log (line 46) | func (r *syslog) Log(level logging.Level, calldepth int, record *loggi...
function NewSyslog (line 37) | func NewSyslog(prefix string) (logging.Backend, error) {
function getGoRoutineID (line 66) | func getGoRoutineID() string {
FILE: network/controller.go
type database (line 38) | type database interface
type LocationStatus (line 42) | type LocationStatus
constant LocationUnregistered (line 46) | LocationUnregistered LocationStatus = iota
constant LocationUndiscovered (line 48) | LocationUndiscovered
constant LocationDiscovered (line 50) | LocationDiscovered
type EventListener (line 53) | type EventListener interface
type ControllerEventListener (line 58) | type ControllerEventListener interface
type TopologyEventListener (line 67) | type TopologyEventListener interface
type Controller (line 71) | type Controller struct
method AddConnection (line 82) | func (r *Controller) AddConnection(ctx context.Context, c net.Conn) {
method SetEventListener (line 93) | func (r *Controller) SetEventListener(l EventListener) {
method String (line 98) | func (r *Controller) String() string {
method Announce (line 102) | func (r *Controller) Announce(ip net.IP, mac net.HardwareAddr) error {
method RemoveFlows (line 114) | func (r *Controller) RemoveFlows() error {
method RemoveFlowsByMAC (line 126) | func (r *Controller) RemoveFlowsByMAC(mac net.HardwareAddr) error {
function NewController (line 76) | func NewController(db database) *Controller {
FILE: network/device.go
type Descriptions (line 39) | type Descriptions struct
type Features (line 47) | type Features struct
type Device (line 53) | type Device struct
method String (line 90) | func (r *Device) String() string {
method ID (line 103) | func (r *Device) ID() string {
method setID (line 111) | func (r *Device) setID(id string) {
method isReady (line 119) | func (r *Device) isReady() bool {
method Factory (line 127) | func (r *Device) Factory() openflow.Factory {
method setFactory (line 135) | func (r *Device) setFactory(f openflow.Factory) {
method Writer (line 146) | func (r *Device) Writer() transceiver.Writer {
method Descriptions (line 154) | func (r *Device) Descriptions() Descriptions {
method setDescriptions (line 162) | func (r *Device) setDescriptions(d Descriptions) {
method Features (line 170) | func (r *Device) Features() Features {
method setFeatures (line 178) | func (r *Device) setFeatures(f Features) {
method Port (line 187) | func (r *Device) Port(num uint32) *Port {
method Ports (line 195) | func (r *Device) Ports() []*Port {
method setPort (line 208) | func (r *Device) setPort(num uint32, p openflow.Port) {
method FlowTableID (line 228) | func (r *Device) FlowTableID() uint8 {
method setFlowTableID (line 236) | func (r *Device) setFlowTableID(id uint8) {
method SendMessage (line 244) | func (r *Device) SendMessage(msg encoding.BinaryMarshaler) error {
method IsClosed (line 259) | func (r *Device) IsClosed() bool {
method SetFlow (line 268) | func (r *Device) SetFlow(match openflow.Match, port openflow.OutPort) ...
method RemoveFlows (line 335) | func (r *Device) RemoveFlows() error {
method RemoveFlow (line 375) | func (r *Device) RemoveFlow(match openflow.Match, port openflow.OutPor...
method RemoveFlowByMAC (line 403) | func (r *Device) RemoveFlowByMAC(mac net.HardwareAddr) error {
method SendARPAnnouncement (line 439) | func (r *Device) SendARPAnnouncement(ip net.IP, mac net.HardwareAddr) ...
method SendARPDiscovery (line 456) | func (r *Device) SendARPDiscovery(sha net.HardwareAddr, spa, tpa net.I...
method Flood (line 490) | func (r *Device) Flood(ingress *Port, packet []byte) error {
method flood (line 503) | func (r *Device) flood(ingress *Port, packet []byte) error {
method Close (line 532) | func (r *Device) Close() {
function newDevice (line 71) | func newDevice(s *session) *Device {
function newARPRequestFrame (line 473) | func newARPRequestFrame(sha net.HardwareAddr, spa, tpa net.IP) ([]byte, ...
FILE: network/error.go
type networkErr (line 24) | type networkErr struct
method Error (line 29) | func (r *networkErr) Error() string {
method Temporary (line 33) | func (r *networkErr) Temporary() bool {
FILE: network/flow_cache.go
type flowCache (line 33) | type flowCache struct
method Add (line 50) | func (r *flowCache) Add(match openflow.Match, port openflow.OutPort) e...
method key (line 64) | func (r *flowCache) key(match openflow.Match, port openflow.OutPort) (...
method InProgress (line 73) | func (r *flowCache) InProgress(match openflow.Match, port openflow.Out...
method RemoveAll (line 95) | func (r *flowCache) RemoveAll() {
function newFlowCache (line 38) | func newFlowCache(expiration time.Duration) *flowCache {
FILE: network/link.go
type link (line 31) | type link struct
method ID (line 41) | func (r *link) ID() string {
method Points (line 48) | func (r *link) Points() [2]graph.Point {
method Weight (line 52) | func (r *link) Weight() float64 {
function newLink (line 35) | func newLink(ports [2]*Port) *link {
FILE: network/node.go
type Node (line 29) | type Node struct
method String (line 41) | func (r *Node) String() string {
method Port (line 45) | func (r *Node) Port() *Port {
method MAC (line 49) | func (r *Node) MAC() net.HardwareAddr {
function NewNode (line 34) | func NewNode(p *Port, mac net.HardwareAddr) *Node {
FILE: network/of10_session.go
type of10Session (line 32) | type of10Session struct
method OnHello (line 46) | func (r *of10Session) OnHello(f openflow.Factory, w transceiver.Writer...
method OnBarrierReply (line 75) | func (r *of10Session) OnBarrierReply(f openflow.Factory, w transceiver...
method OnError (line 93) | func (r *of10Session) OnError(f openflow.Factory, w transceiver.Writer...
method OnFeaturesReply (line 97) | func (r *of10Session) OnFeaturesReply(f openflow.Factory, w transceive...
method OnGetConfigReply (line 122) | func (r *of10Session) OnGetConfigReply(f openflow.Factory, w transceiv...
method OnDescReply (line 126) | func (r *of10Session) OnDescReply(f openflow.Factory, w transceiver.Wr...
method OnPortDescReply (line 130) | func (r *of10Session) OnPortDescReply(f openflow.Factory, w transceive...
method OnPortStatus (line 135) | func (r *of10Session) OnPortStatus(f openflow.Factory, w transceiver.W...
method OnFlowRemoved (line 139) | func (r *of10Session) OnFlowRemoved(f openflow.Factory, w transceiver....
method OnPacketIn (line 143) | func (r *of10Session) OnPacketIn(f openflow.Factory, w transceiver.Wri...
function newOF10Session (line 40) | func newOF10Session(d *Device) *of10Session {
FILE: network/of13_session.go
type of13Session (line 34) | type of13Session struct
method OnHello (line 48) | func (r *of13Session) OnHello(f openflow.Factory, w transceiver.Writer...
method OnBarrierReply (line 77) | func (r *of13Session) OnBarrierReply(f openflow.Factory, w transceiver...
method OnError (line 92) | func (r *of13Session) OnError(f openflow.Factory, w transceiver.Writer...
method OnFeaturesReply (line 96) | func (r *of13Session) OnFeaturesReply(f openflow.Factory, w transceive...
method OnGetConfigReply (line 104) | func (r *of13Session) OnGetConfigReply(f openflow.Factory, w transceiv...
method setTableMiss (line 116) | func (r *of13Session) setTableMiss(f openflow.Factory, w transceiver.W...
method setHP2920TableMiss (line 140) | func (r *of13Session) setHP2920TableMiss(f openflow.Factory, w transce...
method setAS4600TableMiss (line 177) | func (r *of13Session) setAS4600TableMiss(f openflow.Factory, w transce...
method setDefaultTableMiss (line 186) | func (r *of13Session) setDefaultTableMiss(f openflow.Factory, w transc...
method OnDescReply (line 210) | func (r *of13Session) OnDescReply(f openflow.Factory, w transceiver.Wr...
method OnPortDescReply (line 235) | func (r *of13Session) OnPortDescReply(f openflow.Factory, w transceive...
method OnPortStatus (line 260) | func (r *of13Session) OnPortStatus(f openflow.Factory, w transceiver.W...
method OnFlowRemoved (line 264) | func (r *of13Session) OnFlowRemoved(f openflow.Factory, w transceiver....
method OnPacketIn (line 268) | func (r *of13Session) OnPacketIn(f openflow.Factory, w transceiver.Wri...
function newOF13Session (line 42) | func newOF13Session(d *Device) *of13Session {
function isHP2920_24G (line 108) | func isHP2920_24G(msg openflow.DescReply) bool {
function isAS460054_T (line 112) | func isAS460054_T(msg openflow.DescReply) bool {
FILE: network/port.go
type Port (line 33) | type Port struct
method String (line 47) | func (r *Port) String() string {
method ID (line 55) | func (r *Port) ID() string {
method Vertex (line 59) | func (r *Port) Vertex() graph.Vertex {
method Device (line 63) | func (r *Port) Device() *Device {
method Number (line 67) | func (r *Port) Number() uint32 {
method Value (line 71) | func (r *Port) Value() openflow.Port {
method SetValue (line 79) | func (r *Port) SetValue(p openflow.Port) {
function NewPort (line 40) | func NewPort(d *Device, num uint32) *Port {
FILE: network/reserve.go
function ReservedIP (line 31) | func ReservedIP(n net.IPNet) (net.IP, error) {
FILE: network/reserve_test.go
function TestReservedIP (line 29) | func TestReservedIP(t *testing.T) {
FILE: network/session.go
constant deviceExplorerInterval (line 46) | deviceExplorerInterval = 1 * time.Minute
type session (line 49) | type session struct
method OnHello (line 95) | func (r *session) OnHello(f openflow.Factory, w transceiver.Writer, v ...
method OnError (line 117) | func (r *session) OnError(f openflow.Factory, w transceiver.Writer, v ...
method OnFeaturesReply (line 133) | func (r *session) OnFeaturesReply(f openflow.Factory, w transceiver.Wr...
method OnGetConfigReply (line 174) | func (r *session) OnGetConfigReply(f openflow.Factory, w transceiver.W...
method OnDescReply (line 184) | func (r *session) OnDescReply(f openflow.Factory, w transceiver.Writer...
method OnPortDescReply (line 205) | func (r *session) OnPortDescReply(f openflow.Factory, w transceiver.Wr...
method sendPortEvent (line 276) | func (r *session) sendPortEvent(portNum uint32, up bool) {
method updatePort (line 295) | func (r *session) updatePort(v openflow.PortStatus) {
method OnPortStatus (line 313) | func (r *session) OnPortStatus(f openflow.Factory, w transceiver.Write...
method OnFlowRemoved (line 345) | func (r *session) OnFlowRemoved(f openflow.Factory, w transceiver.Writ...
method findNeighborPort (line 414) | func (r *session) findNeighborPort(deviceID string, portNum uint32) (*...
method handleLLDP (line 427) | func (r *session) handleLLDP(inPort *Port, ethernet *protocol.Ethernet...
method OnPacketIn (line 449) | func (r *session) OnPacketIn(f openflow.Factory, w transceiver.Writer,...
method OnBarrierReply (line 492) | func (r *session) OnBarrierReply(f openflow.Factory, w transceiver.Wri...
method Run (line 501) | func (r *session) Run(ctx context.Context) {
method runDeviceExplorer (line 521) | func (r *session) runDeviceExplorer(ctx context.Context) context.Cance...
method Write (line 568) | func (r *session) Write(msg encoding.BinaryMarshaler) error {
type sessionConfig (line 59) | type sessionConfig struct
function checkParam (line 66) | func checkParam(c sessionConfig) {
function newSession (line 81) | func newSession(c sessionConfig) *session {
function newLLDPEtherFrame (line 215) | func newLLDPEtherFrame(deviceID string, port openflow.Port) ([]byte, err...
function sendLLDP (line 248) | func sendLLDP(device *Device, p openflow.Port) error {
function getEthernet (line 360) | func getEthernet(packet []byte) (*protocol.Ethernet, error) {
function isLLDP (line 369) | func isLLDP(e *protocol.Ethernet) bool {
function getLLDP (line 373) | func getLLDP(packet []byte) (*protocol.LLDP, error) {
function isCherryLLDP (line 382) | func isCherryLLDP(p *protocol.LLDP) bool {
function extractDeviceInfo (line 399) | func extractDeviceInfo(p *protocol.LLDP) (deviceID string, portNum uint3...
function sendHello (line 572) | func sendHello(f openflow.Factory, w transceiver.Writer) error {
function sendSetConfig (line 581) | func sendSetConfig(f openflow.Factory, w transceiver.Writer) error {
function sendFeaturesRequest (line 592) | func sendFeaturesRequest(f openflow.Factory, w transceiver.Writer) error {
function sendDescriptionRequest (line 601) | func sendDescriptionRequest(f openflow.Factory, w transceiver.Writer) er...
function sendBarrierRequest (line 610) | func sendBarrierRequest(f openflow.Factory, w transceiver.Writer) error {
function sendPortDescriptionRequest (line 619) | func sendPortDescriptionRequest(f openflow.Factory, w transceiver.Writer...
function setARPSender (line 629) | func setARPSender(f openflow.Factory, w transceiver.Writer) error {
function setLLDPSender (line 641) | func setLLDPSender(f openflow.Factory, w transceiver.Writer) error {
function setTemporaryDrop (line 653) | func setTemporaryDrop(f openflow.Factory, w transceiver.Writer) error {
function setDHCPSender (line 664) | func setDHCPSender(f openflow.Factory, w transceiver.Writer) error {
function setSpecialFlow (line 678) | func setSpecialFlow(f openflow.Factory, w transceiver.Writer, match open...
function sendRemoveAllFlows (line 711) | func sendRemoveAllFlows(f openflow.Factory, w transceiver.Writer) error {
FILE: network/topology.go
type watcher (line 36) | type watcher interface
type Finder (line 43) | type Finder interface
type topology (line 54) | type topology struct
method String (line 74) | func (r *topology) String() string {
method setEventListener (line 85) | func (r *topology) setEventListener(l TopologyEventListener) {
method sendEvent (line 91) | func (r *topology) sendEvent() {
method Devices (line 102) | func (r *topology) Devices() []*Device {
method Device (line 116) | func (r *topology) Device(id string) *Device {
method DeviceAdded (line 124) | func (r *topology) DeviceAdded(d *Device) {
method removeDevice (line 139) | func (r *topology) removeDevice(d *Device) {
method DeviceRemoved (line 144) | func (r *topology) DeviceRemoved(d *Device) {
method DeviceLinked (line 158) | func (r *topology) DeviceLinked(ports [2]*Port) {
method Node (line 185) | func (r *topology) Node(mac net.HardwareAddr) (*Node, LocationStatus, ...
method PortRemoved (line 210) | func (r *topology) PortRemoved(p *Port) {
method Path (line 231) | func (r *topology) Path(srcDeviceID, dstDeviceID string) [][2]*Port {
method IsEdge (line 264) | func (r *topology) IsEdge(p *Port) bool {
method IsEnabledBySTP (line 268) | func (r *topology) IsEnabledBySTP(p *Port) bool {
method staleEdgeRemover (line 273) | func (r *topology) staleEdgeRemover() {
function newTopology (line 63) | func newTopology(db database) *topology {
function pickPort (line 255) | func pickPort(d *Device, l *link) [2]*Port {
FILE: northbound/app/announcer/announcer.go
type Announcer (line 46) | type Announcer struct
method Init (line 68) | func (r *Announcer) Init() error {
method Name (line 72) | func (r *Announcer) Name() string {
method String (line 76) | func (r *Announcer) String() string {
method OnDeviceUp (line 80) | func (r *Announcer) OnDeviceUp(finder network.Finder, device *network....
method broadcaster (line 90) | func (r *Announcer) broadcaster(finder network.Finder) {
type database (line 52) | type database interface
type ARPTableEntry (line 57) | type ARPTableEntry struct
function New (line 62) | func New(db database) *Announcer {
FILE: northbound/app/announcer/backoff.go
type backoff (line 36) | type backoff struct
method Broadcast (line 58) | func (r *backoff) Broadcast(ip net.IP, mac net.HardwareAddr) error {
method getAnnouncer (line 65) | func (r *backoff) getAnnouncer(ip net.IP, mac net.HardwareAddr) *annou...
function newBackoff (line 43) | func newBackoff(finder network.Finder) *backoff {
type announcer (line 83) | type announcer struct
method Broadcast (line 91) | func (r *announcer) Broadcast() error {
method calculateDelay (line 117) | func (r *announcer) calculateDelay() time.Duration {
constant maxDelay (line 115) | maxDelay = 1 * time.Hour
FILE: northbound/app/dhcp/dhcp.go
type DHCP (line 47) | type DHCP struct
method Init (line 69) | func (r *DHCP) Init() error {
method Name (line 73) | func (r *DHCP) Name() string {
method String (line 77) | func (r *DHCP) String() string {
method OnPacketIn (line 81) | func (r *DHCP) OnPacketIn(finder network.Finder, ingress *network.Port...
method processDHCPPacket (line 120) | func (r *DHCP) processDHCPPacket(ingress *network.Port, dhcp *protocol...
method processDHCPDiscover (line 168) | func (r *DHCP) processDHCPDiscover(ingress *network.Port, disc *protoc...
method processDHCPRequest (line 201) | func (r *DHCP) processDHCPRequest(ingress *network.Port, req *protocol...
type Database (line 52) | type Database interface
type NetConfig (line 57) | type NetConfig struct
function New (line 63) | func New(db Database) *DHCP {
function buildReply (line 242) | func buildReply(dstMAC net.HardwareAddr, dstIP net.IP, dhcp *protocol.DH...
function sendReply (line 276) | func sendReply(ingress *network.Port, packet []byte) error {
FILE: northbound/app/discovery/discovery.go
constant ProbeInterval (line 48) | ProbeInterval = 30 * time.Second
type processor (line 51) | type processor struct
method Name (line 85) | func (r *processor) Name() string {
method String (line 89) | func (r *processor) String() string {
method OnDeviceUp (line 93) | func (r *processor) OnDeviceUp(finder network.Finder, device *network....
method runARPSender (line 102) | func (r *processor) runARPSender(device *network.Device) {
method sendARPDiscovery (line 129) | func (r *processor) sendARPDiscovery(device *network.Device) error {
method stopARPSender (line 155) | func (r *processor) stopARPSender(deviceID string) {
method OnPacketIn (line 167) | func (r *processor) OnPacketIn(finder network.Finder, ingress *network...
method processARPRequest (line 191) | func (r *processor) processARPRequest(finder network.Finder, ingress *...
method processARPReply (line 203) | func (r *processor) processARPReply(finder network.Finder, ingress *ne...
method macLearning (line 221) | func (r *processor) macLearning(finder network.Finder, ingress *networ...
method OnPortDown (line 250) | func (r *processor) OnPortDown(finder network.Finder, port *network.Po...
method OnDeviceDown (line 266) | func (r *processor) OnDeviceDown(finder network.Finder, device *networ...
method OnTopologyChange (line 285) | func (r *processor) OnTopologyChange(finder network.Finder) error {
type Database (line 59) | type Database interface
function New (line 78) | func New(db Database) app.Processor {
FILE: northbound/app/l2switch/storm_controller.go
type stormController (line 33) | type stormController struct
method broadcast (line 60) | func (r *stormController) broadcast(ingress *network.Port, packet []by...
type broadcaster (line 40) | type broadcaster interface
function newStormController (line 45) | func newStormController(max uint, bcaster broadcaster) *stormController {
FILE: northbound/app/l2switch/storm_controller_test.go
function TestStorm (line 32) | func TestStorm(t *testing.T) {
function TestPeriodicBroadcast (line 60) | func TestPeriodicBroadcast(t *testing.T) {
function TestPeriodicStorm (line 74) | func TestPeriodicStorm(t *testing.T) {
type dummyFlooder (line 92) | type dummyFlooder struct
method flood (line 96) | func (r *dummyFlooder) flood(ingress *network.Port, packet []byte) err...
method getCounter (line 101) | func (r *dummyFlooder) getCounter() uint64 {
FILE: northbound/app/l2switch/switch.go
type L2Switch (line 45) | type L2Switch struct
method Init (line 71) | func (r *L2Switch) Init() error {
method Name (line 75) | func (r *L2Switch) Name() string {
method setFlow (line 93) | func (r *L2Switch) setFlow(p flowParam) error {
method switching (line 120) | func (r *L2Switch) switching(p switchParam) error {
method OnPacketIn (line 135) | func (r *L2Switch) OnPacketIn(finder network.Finder, ingress *network....
method processPacket (line 144) | func (r *L2Switch) processPacket(finder network.Finder, ingress *netwo...
method OnTopologyChange (line 220) | func (r *L2Switch) OnTopologyChange(finder network.Finder) error {
method removeAllFlows (line 232) | func (r *L2Switch) removeAllFlows(devices []*network.Device) error {
method String (line 248) | func (r *L2Switch) String() string {
method OnPortDown (line 252) | func (r *L2Switch) OnPortDown(finder network.Finder, port *network.Por...
method OnDeviceUp (line 273) | func (r *L2Switch) OnDeviceUp(finder network.Finder, device *network.D...
method flowManager (line 283) | func (r *L2Switch) flowManager(finder network.Finder) {
method modifyFlows (line 304) | func (r *L2Switch) modifyFlows(finder network.Finder, mac net.Hardware...
type Database (line 52) | type Database interface
function New (line 57) | func New(db Database) *L2Switch {
type flooder (line 64) | type flooder struct
method flood (line 67) | func (r *flooder) flood(ingress *network.Port, packet []byte) error {
function isBroadcast (line 79) | func isBroadcast(eth *protocol.Ethernet) bool {
type flowParam (line 83) | type flowParam struct
method String (line 89) | func (r flowParam) String() string {
type switchParam (line 112) | type switchParam struct
FILE: northbound/app/monitor/monitor.go
type Monitor (line 40) | type Monitor struct
method Init (line 49) | func (r *Monitor) Init() error {
method Name (line 59) | func (r *Monitor) Name() string {
method String (line 63) | func (r *Monitor) String() string {
method OnDeviceUp (line 67) | func (r *Monitor) OnDeviceUp(finder network.Finder, device *network.De...
method OnDeviceDown (line 80) | func (r *Monitor) OnDeviceDown(finder network.Finder, device *network....
method sendAlarm (line 93) | func (r *Monitor) sendAlarm(subject, body string) error {
function New (line 45) | func New() *Monitor {
FILE: northbound/app/monitor/sendmail.go
function sendmail (line 14) | func sendmail(from string, to []string, msg []byte) error {
function lookupMX (line 33) | func lookupMX(email string) ([]*net.MX, error) {
FILE: northbound/app/processor.go
type Processor (line 33) | type Processor interface
type BaseProcessor (line 44) | type BaseProcessor struct
method Init (line 48) | func (r *BaseProcessor) Init() error {
method Name (line 52) | func (r *BaseProcessor) Name() string {
method Dependencies (line 56) | func (r *BaseProcessor) Dependencies() []string {
method OnPacketIn (line 60) | func (r *BaseProcessor) OnPacketIn(finder network.Finder, ingress *net...
method OnDeviceUp (line 69) | func (r *BaseProcessor) OnDeviceUp(finder network.Finder, device *netw...
method OnDeviceDown (line 78) | func (r *BaseProcessor) OnDeviceDown(finder network.Finder, device *ne...
method OnPortUp (line 87) | func (r *BaseProcessor) OnPortUp(finder network.Finder, port *network....
method OnPortDown (line 96) | func (r *BaseProcessor) OnPortDown(finder network.Finder, port *networ...
method OnTopologyChange (line 105) | func (r *BaseProcessor) OnTopologyChange(finder network.Finder) error {
method OnFlowRemoved (line 114) | func (r *BaseProcessor) OnFlowRemoved(finder network.Finder, flow open...
method Next (line 123) | func (r *BaseProcessor) Next() (next Processor, ok bool) {
method SetNext (line 131) | func (r *BaseProcessor) SetNext(next Processor) {
method PacketOut (line 135) | func (r *BaseProcessor) PacketOut(egress *network.Port, packet []byte)...
FILE: northbound/app/proxyarp/arp.go
type ProxyARP (line 42) | type ProxyARP struct
method Init (line 62) | func (r *ProxyARP) Init() error {
method Name (line 66) | func (r *ProxyARP) Name() string {
method OnPacketIn (line 70) | func (r *ProxyARP) OnPacketIn(finder network.Finder, ingress *network....
method String (line 170) | func (r *ProxyARP) String() string {
type database (line 47) | type database interface
type Host (line 51) | type Host struct
function New (line 56) | func New(db database) *ProxyARP {
function sendARPReply (line 116) | func sendARPReply(ingress *network.Port, packet []byte) error {
function isARPAnnouncement (line 142) | func isARPAnnouncement(request *protocol.ARP) bool {
function makeARPReply (line 154) | func makeARPReply(request *protocol.ARP, mac net.HardwareAddr) ([]byte, ...
FILE: northbound/app/proxyarp/error.go
type proxyarpErr (line 24) | type proxyarpErr struct
method Error (line 29) | func (r *proxyarpErr) Error() string {
method Temporary (line 33) | func (r *proxyarpErr) Temporary() bool {
FILE: northbound/app/virtualip/virtualip.go
type VirtualIP (line 40) | type VirtualIP struct
method Init (line 61) | func (r *VirtualIP) Init() error {
method Name (line 65) | func (r *VirtualIP) Name() string {
method String (line 69) | func (r *VirtualIP) String() string {
method OnPortDown (line 73) | func (r *VirtualIP) OnPortDown(finder network.Finder, port *network.Po...
method OnDeviceDown (line 91) | func (r *VirtualIP) OnDeviceDown(finder network.Finder, device *networ...
type database (line 45) | type database interface
type Address (line 50) | type Address struct
function New (line 55) | func New(db database) *VirtualIP {
function broadcastARPAnnouncement (line 109) | func broadcastARPAnnouncement(finder network.Finder, vips []Address) {
FILE: northbound/manager.go
type EventSender (line 49) | type EventSender interface
type application (line 53) | type application struct
type Manager (line 58) | type Manager struct
method register (line 82) | func (r *Manager) register(app app.Processor) {
method checkDependencies (line 90) | func (r *Manager) checkDependencies(appNames []string) error {
method Enable (line 107) | func (r *Manager) Enable(appName string) error {
method AddEventSender (line 142) | func (r *Manager) AddEventSender(sender EventSender) {
method String (line 152) | func (r *Manager) String() string {
function NewManager (line 65) | func NewManager(db *database.MySQL) (*Manager, error) {
FILE: openflow/action.go
type Action (line 31) | type Action interface
type BaseAction (line 48) | type BaseAction struct
method VLANID (line 64) | func (r *BaseAction) VLANID() (ok bool, vid uint16) {
method SetVLANID (line 72) | func (r *BaseAction) SetVLANID(vid uint16) {
method Queue (line 76) | func (r *BaseAction) Queue() (ok bool, queue uint32) {
method SetQueue (line 84) | func (r *BaseAction) SetQueue(queue uint32) {
method SetOutPort (line 88) | func (r *BaseAction) SetOutPort(port OutPort) {
method OutPort (line 92) | func (r *BaseAction) OutPort() OutPort {
method SetSrcMAC (line 96) | func (r *BaseAction) SetSrcMAC(mac net.HardwareAddr) {
method SrcMAC (line 105) | func (r *BaseAction) SrcMAC() (ok bool, mac net.HardwareAddr) {
method SetDstMAC (line 113) | func (r *BaseAction) SetDstMAC(mac net.HardwareAddr) {
method DstMAC (line 122) | func (r *BaseAction) DstMAC() (ok bool, mac net.HardwareAddr) {
method Error (line 130) | func (r *BaseAction) Error() error {
function NewBaseAction (line 57) | func NewBaseAction() *BaseAction {
FILE: openflow/barrier.go
type BarrierRequest (line 28) | type BarrierRequest interface
type BarrierReply (line 33) | type BarrierReply interface
FILE: openflow/config.go
type ConfigFlag (line 28) | type ConfigFlag
constant FragNormal (line 31) | FragNormal ConfigFlag = iota
constant FragDrop (line 32) | FragDrop
constant FragReasm (line 33) | FragReasm
constant FragMask (line 34) | FragMask
type Config (line 37) | type Config interface
type SetConfig (line 46) | type SetConfig interface
type GetConfigRequest (line 52) | type GetConfigRequest interface
type GetConfigReply (line 57) | type GetConfigReply interface
FILE: openflow/const.go
constant OF10_VERSION (line 25) | OF10_VERSION = 0x01
constant OF13_VERSION (line 26) | OF13_VERSION = 0x04
FILE: openflow/description.go
type DescRequest (line 29) | type DescRequest interface
type DescReply (line 35) | type DescReply interface
FILE: openflow/echo.go
type Echo (line 28) | type Echo interface
type EchoRequest (line 38) | type EchoRequest interface
type EchoReply (line 42) | type EchoReply interface
type BaseEcho (line 46) | type BaseEcho struct
method Data (line 52) | func (r *BaseEcho) Data() []byte {
method SetData (line 56) | func (r *BaseEcho) SetData(data []byte) {
method Error (line 63) | func (r *BaseEcho) Error() error {
method MarshalBinary (line 67) | func (r *BaseEcho) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 76) | func (r *BaseEcho) UnmarshalBinary(data []byte) error {
FILE: openflow/error.go
type Error (line 29) | type Error interface
type BaseError (line 37) | type BaseError struct
method Class (line 44) | func (r *BaseError) Class() uint16 {
method Code (line 48) | func (r *BaseError) Code() uint16 {
method Data (line 52) | func (r *BaseError) Data() []byte {
method UnmarshalBinary (line 56) | func (r *BaseError) UnmarshalBinary(data []byte) error {
FILE: openflow/factory.go
type Factory (line 43) | type Factory interface
FILE: openflow/features.go
type FeaturesRequest (line 28) | type FeaturesRequest interface
type FeaturesReply (line 33) | type FeaturesReply interface
FILE: openflow/flow_mod.go
type FlowModCmd (line 28) | type FlowModCmd
constant FlowAdd (line 31) | FlowAdd FlowModCmd = iota
constant FlowModify (line 32) | FlowModify
constant FlowDelete (line 33) | FlowDelete
type FlowMod (line 36) | type FlowMod interface
FILE: openflow/flow_removed.go
type FlowRemoved (line 28) | type FlowRemoved interface
FILE: openflow/flow_stats.go
type FlowStatsRequest (line 28) | type FlowStatsRequest interface
FILE: openflow/hello.go
type Hello (line 28) | type Hello interface
type BaseHello (line 34) | type BaseHello struct
method MarshalBinary (line 38) | func (r *BaseHello) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 42) | func (r *BaseHello) UnmarshalBinary(data []byte) error {
FILE: openflow/instruction.go
type Instruction (line 28) | type Instruction interface
FILE: openflow/match.go
type Match (line 29) | type Match interface
FILE: openflow/message.go
type Header (line 28) | type Header interface
type Message (line 35) | type Message struct
method Version (line 52) | func (r *Message) Version() uint8 {
method Type (line 56) | func (r *Message) Type() uint8 {
method TransactionID (line 60) | func (r *Message) TransactionID() uint32 {
method SetTransactionID (line 64) | func (r *Message) SetTransactionID(xid uint32) {
method Payload (line 68) | func (r *Message) Payload() []byte {
method SetPayload (line 72) | func (r *Message) SetPayload(payload []byte) {
method MarshalBinary (line 81) | func (r *Message) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 99) | func (r *Message) UnmarshalBinary(data []byte) error {
function NewMessage (line 43) | func NewMessage(version uint8, msgType uint8, xid uint32) Message {
FILE: openflow/of10/action.go
type Action (line 31) | type Action struct
method MarshalBinary (line 120) | func (r *Action) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 168) | func (r *Action) UnmarshalBinary(data []byte) error {
function NewAction (line 35) | func NewAction() openflow.Action {
function marshalOutPort (line 41) | func marshalOutPort(p openflow.OutPort) ([]byte, error) {
function marshalQueue (line 70) | func marshalQueue(p openflow.OutPort, queue uint32) ([]byte, error) {
function marshalMAC (line 97) | func marshalMAC(t uint16, mac net.HardwareAddr) ([]byte, error) {
function marshalVLANID (line 110) | func marshalVLANID(vid uint16) ([]byte, error) {
FILE: openflow/of10/barrier.go
type BarrierRequest (line 28) | type BarrierRequest struct
method MarshalBinary (line 38) | func (r *BarrierRequest) MarshalBinary() ([]byte, error) {
function NewBarrierRequest (line 32) | func NewBarrierRequest(xid uint32) openflow.BarrierRequest {
type BarrierReply (line 42) | type BarrierReply struct
method UnmarshalBinary (line 46) | func (r *BarrierReply) UnmarshalBinary(data []byte) error {
FILE: openflow/of10/config.go
type Config (line 31) | type Config struct
method Flags (line 37) | func (r *Config) Flags() openflow.ConfigFlag {
method SetFlags (line 52) | func (r *Config) SetFlags(flags openflow.ConfigFlag) {
method MissSendLength (line 67) | func (r *Config) MissSendLength() uint16 {
method SetMissSendLength (line 71) | func (r *Config) SetMissSendLength(length uint16) {
method Error (line 75) | func (r *Config) Error() error {
type SetConfig (line 79) | type SetConfig struct
method MarshalBinary (line 94) | func (r *SetConfig) MarshalBinary() ([]byte, error) {
function NewSetConfig (line 84) | func NewSetConfig(xid uint32) openflow.SetConfig {
type GetConfigRequest (line 107) | type GetConfigRequest struct
method MarshalBinary (line 117) | func (r *GetConfigRequest) MarshalBinary() ([]byte, error) {
function NewGetConfigRequest (line 111) | func NewGetConfigRequest(xid uint32) openflow.GetConfigRequest {
type GetConfigReply (line 121) | type GetConfigReply struct
method UnmarshalBinary (line 126) | func (r *GetConfigReply) UnmarshalBinary(data []byte) error {
FILE: openflow/of10/const.go
constant OFPT_HELLO (line 25) | OFPT_HELLO = iota
constant OFPT_ERROR (line 26) | OFPT_ERROR
constant OFPT_ECHO_REQUEST (line 27) | OFPT_ECHO_REQUEST
constant OFPT_ECHO_REPLY (line 28) | OFPT_ECHO_REPLY
constant OFPT_VENDOR (line 29) | OFPT_VENDOR
constant OFPT_FEATURES_REQUEST (line 30) | OFPT_FEATURES_REQUEST
constant OFPT_FEATURES_REPLY (line 31) | OFPT_FEATURES_REPLY
constant OFPT_GET_CONFIG_REQUEST (line 32) | OFPT_GET_CONFIG_REQUEST
constant OFPT_GET_CONFIG_REPLY (line 33) | OFPT_GET_CONFIG_REPLY
constant OFPT_SET_CONFIG (line 34) | OFPT_SET_CONFIG
constant OFPT_PACKET_IN (line 35) | OFPT_PACKET_IN
constant OFPT_FLOW_REMOVED (line 36) | OFPT_FLOW_REMOVED
constant OFPT_PORT_STATUS (line 37) | OFPT_PORT_STATUS
constant OFPT_PACKET_OUT (line 38) | OFPT_PACKET_OUT
constant OFPT_FLOW_MOD (line 39) | OFPT_FLOW_MOD
constant OFPT_PORT_MOD (line 40) | OFPT_PORT_MOD
constant OFPT_STATS_REQUEST (line 41) | OFPT_STATS_REQUEST
constant OFPT_STATS_REPLY (line 42) | OFPT_STATS_REPLY
constant OFPT_BARRIER_REQUEST (line 43) | OFPT_BARRIER_REQUEST
constant OFPT_BARRIER_REPLY (line 44) | OFPT_BARRIER_REPLY
constant OFPT_QUEUE_GET_CONFIG_REQUEST (line 45) | OFPT_QUEUE_GET_CONFIG_REQUEST
constant OFPT_QUEUE_GET_CONFIG_REPLY (line 46) | OFPT_QUEUE_GET_CONFIG_REPLY
constant OFPAT_OUTPUT (line 50) | OFPAT_OUTPUT = iota
constant OFPAT_SET_VLAN_VID (line 51) | OFPAT_SET_VLAN_VID
constant OFPAT_SET_VLAN_PCP (line 52) | OFPAT_SET_VLAN_PCP
constant OFPAT_STRIP_VLAN (line 53) | OFPAT_STRIP_VLAN
constant OFPAT_SET_DL_SRC (line 54) | OFPAT_SET_DL_SRC
constant OFPAT_SET_DL_DST (line 55) | OFPAT_SET_DL_DST
constant OFPAT_SET_NW_SRC (line 56) | OFPAT_SET_NW_SRC
constant OFPAT_SET_NW_DST (line 57) | OFPAT_SET_NW_DST
constant OFPAT_SET_NW_TOS (line 58) | OFPAT_SET_NW_TOS
constant OFPAT_SET_TP_SRC (line 59) | OFPAT_SET_TP_SRC
constant OFPAT_SET_TP_DST (line 60) | OFPAT_SET_TP_DST
constant OFPAT_ENQUEUE (line 61) | OFPAT_ENQUEUE
constant OFPAT_VENDOR (line 62) | OFPAT_VENDOR = 0xffff
constant OFPP_MAX (line 66) | OFPP_MAX = 0xff00
constant OFPP_IN_PORT (line 67) | OFPP_IN_PORT = 0xfff8
constant OFPP_TABLE (line 68) | OFPP_TABLE = 0xfff9
constant OFPP_FLOOD (line 69) | OFPP_FLOOD = 0xfffb
constant OFPP_ALL (line 70) | OFPP_ALL = 0xfffc
constant OFPP_CONTROLLER (line 71) | OFPP_CONTROLLER = 0xfffd
constant OFPP_NONE (line 72) | OFPP_NONE = 0xffff
constant OFPFW_IN_PORT (line 76) | OFPFW_IN_PORT = 1 << 0
constant OFPFW_DL_VLAN (line 77) | OFPFW_DL_VLAN = 1 << 1
constant OFPFW_DL_SRC (line 78) | OFPFW_DL_SRC = 1 << 2
constant OFPFW_DL_DST (line 79) | OFPFW_DL_DST = 1 << 3
constant OFPFW_DL_TYPE (line 80) | OFPFW_DL_TYPE = 1 << 4
constant OFPFW_NW_PROTO (line 81) | OFPFW_NW_PROTO = 1 << 5
constant OFPFW_TP_SRC (line 82) | OFPFW_TP_SRC = 1 << 6
constant OFPFW_TP_DST (line 83) | OFPFW_TP_DST = 1 << 7
constant OFPFW_DL_VLAN_PCP (line 84) | OFPFW_DL_VLAN_PCP = 1 << 20
constant OFPFW_NW_TOS (line 85) | OFPFW_NW_TOS = 1 << 21
constant OFPPF_10MB_HD (line 89) | OFPPF_10MB_HD = 1 << 0
constant OFPPF_10MB_FD (line 90) | OFPPF_10MB_FD = 1 << 1
constant OFPPF_100MB_HD (line 91) | OFPPF_100MB_HD = 1 << 2
constant OFPPF_100MB_FD (line 92) | OFPPF_100MB_FD = 1 << 3
constant OFPPF_1GB_HD (line 93) | OFPPF_1GB_HD = 1 << 4
constant OFPPF_1GB_FD (line 94) | OFPPF_1GB_FD = 1 << 5
constant OFPPF_10GB_FD (line 95) | OFPPF_10GB_FD = 1 << 6
constant OFPPF_COPPER (line 96) | OFPPF_COPPER = 1 << 7
constant OFPPF_FIBER (line 97) | OFPPF_FIBER = 1 << 8
constant OFPPF_AUTONEG (line 98) | OFPPF_AUTONEG = 1 << 9
constant OFPPF_PAUSE (line 99) | OFPPF_PAUSE = 1 << 10
constant OFPPF_PAUSE_ASYM (line 100) | OFPPF_PAUSE_ASYM = 1 << 11
constant OFPPC_PORT_DOWN (line 104) | OFPPC_PORT_DOWN = 1 << 0
constant OFPPC_NO_STP (line 105) | OFPPC_NO_STP = 1 << 1
constant OFPPC_NO_RECV (line 106) | OFPPC_NO_RECV = 1 << 2
constant OFPPC_NO_RECV_STP (line 107) | OFPPC_NO_RECV_STP = 1 << 3
constant OFPPC_NO_FLOOD (line 108) | OFPPC_NO_FLOOD = 1 << 4
constant OFPPC_NO_FWD (line 109) | OFPPC_NO_FWD = 1 << 5
constant OFPPC_NO_PACKET_IN (line 110) | OFPPC_NO_PACKET_IN = 1 << 6
constant OFPPS_LINK_DOWN (line 114) | OFPPS_LINK_DOWN = 1 << 0
constant OFPPS_STP_LISTEN (line 115) | OFPPS_STP_LISTEN = 0 << 8
constant OFPPS_STP_LEARN (line 116) | OFPPS_STP_LEARN = 1 << 8
constant OFPPS_STP_FORWARD (line 117) | OFPPS_STP_FORWARD = 2 << 8
constant OFPPS_STP_BLOCK (line 118) | OFPPS_STP_BLOCK = 3 << 8
constant OFPPS_STP_MASK (line 119) | OFPPS_STP_MASK = 3 << 8
constant OFPFF_SEND_FLOW_REM (line 123) | OFPFF_SEND_FLOW_REM = 1 << 0
constant OFPFF_CHECK_OVERLAP (line 124) | OFPFF_CHECK_OVERLAP = 1 << 1
constant OFPFF_EMERG (line 125) | OFPFF_EMERG = 1 << 2
constant OFP_NO_BUFFER (line 129) | OFP_NO_BUFFER = 0xffffffff
constant OFPFC_ADD (line 133) | OFPFC_ADD = 0
constant OFPFC_MODIFY (line 134) | OFPFC_MODIFY = 1
constant OFPFC_MODIFY_STRICT (line 135) | OFPFC_MODIFY_STRICT = 2
constant OFPFC_DELETE (line 136) | OFPFC_DELETE = 3
constant OFPFC_DELETE_STRICT (line 137) | OFPFC_DELETE_STRICT = 4
constant OFPST_DESC (line 144) | OFPST_DESC = iota
constant OFPST_FLOW (line 148) | OFPST_FLOW
constant OFPST_AGGREGATE (line 152) | OFPST_AGGREGATE
constant OFPST_TABLE (line 156) | OFPST_TABLE
constant OFPST_PORT (line 160) | OFPST_PORT
constant OFPST_QUEUE (line 164) | OFPST_QUEUE
constant OFPST_VENDOR (line 169) | OFPST_VENDOR = 0xffff
constant OFPC_FRAG_NORMAL (line 173) | OFPC_FRAG_NORMAL = iota
constant OFPC_FRAG_DROP (line 174) | OFPC_FRAG_DROP
constant OFPC_FRAG_REASM (line 175) | OFPC_FRAG_REASM
constant OFPC_FRAG_MASK (line 176) | OFPC_FRAG_MASK
constant OFPPR_ADD (line 180) | OFPPR_ADD = 0
constant OFPPR_DELETE (line 181) | OFPPR_DELETE = 1
constant OFPPR_MODIFY (line 182) | OFPPR_MODIFY = 2
FILE: openflow/of10/description.go
type DescRequest (line 31) | type DescRequest struct
method MarshalBinary (line 41) | func (r *DescRequest) MarshalBinary() ([]byte, error) {
function NewDescRequest (line 35) | func NewDescRequest(xid uint32) openflow.DescRequest {
type DescReply (line 50) | type DescReply struct
method Manufacturer (line 59) | func (r DescReply) Manufacturer() string {
method Hardware (line 63) | func (r DescReply) Hardware() string {
method Software (line 67) | func (r DescReply) Software() string {
method Serial (line 71) | func (r DescReply) Serial() string {
method Description (line 75) | func (r DescReply) Description() string {
method UnmarshalBinary (line 79) | func (r *DescReply) UnmarshalBinary(data []byte) error {
FILE: openflow/of10/echo.go
function NewEchoRequest (line 28) | func NewEchoRequest(xid uint32) openflow.EchoRequest {
function NewEchoReply (line 34) | func NewEchoReply(xid uint32) openflow.EchoReply {
FILE: openflow/of10/factory.go
type Factory (line 33) | type Factory struct
method ProtocolVersion (line 41) | func (r *Factory) ProtocolVersion() uint8 {
method getTransactionID (line 45) | func (r *Factory) getTransactionID() uint32 {
method NewHello (line 50) | func (r *Factory) NewHello() (openflow.Hello, error) {
method NewEchoRequest (line 54) | func (r *Factory) NewEchoRequest() (openflow.EchoRequest, error) {
method NewEchoReply (line 58) | func (r *Factory) NewEchoReply() (openflow.EchoReply, error) {
method NewAction (line 62) | func (r *Factory) NewAction() (openflow.Action, error) {
method NewMatch (line 66) | func (r *Factory) NewMatch() (openflow.Match, error) {
method NewBarrierRequest (line 70) | func (r *Factory) NewBarrierRequest() (openflow.BarrierRequest, error) {
method NewBarrierReply (line 74) | func (r *Factory) NewBarrierReply() (openflow.BarrierReply, error) {
method NewSetConfig (line 78) | func (r *Factory) NewSetConfig() (openflow.SetConfig, error) {
method NewGetConfigRequest (line 82) | func (r *Factory) NewGetConfigRequest() (openflow.GetConfigRequest, er...
method NewGetConfigReply (line 86) | func (r *Factory) NewGetConfigReply() (openflow.GetConfigReply, error) {
method NewFeaturesRequest (line 90) | func (r *Factory) NewFeaturesRequest() (openflow.FeaturesRequest, erro...
method NewFeaturesReply (line 94) | func (r *Factory) NewFeaturesReply() (openflow.FeaturesReply, error) {
method NewFlowMod (line 114) | func (r *Factory) NewFlowMod(cmd openflow.FlowModCmd) (openflow.FlowMo...
method NewFlowRemoved (line 118) | func (r *Factory) NewFlowRemoved() (openflow.FlowRemoved, error) {
method NewPacketIn (line 122) | func (r *Factory) NewPacketIn() (openflow.PacketIn, error) {
method NewPacketOut (line 126) | func (r *Factory) NewPacketOut() (openflow.PacketOut, error) {
method NewPortStatus (line 130) | func (r *Factory) NewPortStatus() (openflow.PortStatus, error) {
method NewDescRequest (line 134) | func (r *Factory) NewDescRequest() (openflow.DescRequest, error) {
method NewDescReply (line 138) | func (r *Factory) NewDescReply() (openflow.DescReply, error) {
method NewFlowStatsRequest (line 142) | func (r *Factory) NewFlowStatsRequest() (openflow.FlowStatsRequest, er...
method NewPortDescRequest (line 148) | func (r *Factory) NewPortDescRequest() (openflow.PortDescRequest, erro...
method NewPortDescReply (line 152) | func (r *Factory) NewPortDescReply() (openflow.PortDescReply, error) {
method NewTableFeaturesRequest (line 156) | func (r *Factory) NewTableFeaturesRequest() (openflow.TableFeaturesReq...
method NewError (line 160) | func (r *Factory) NewError() (openflow.Error, error) {
method NewInstruction (line 166) | func (r *Factory) NewInstruction() (openflow.Instruction, error) {
method NewQueueGetConfigRequest (line 170) | func (r *Factory) NewQueueGetConfigRequest() (openflow.QueueGetConfigR...
function NewFactory (line 37) | func NewFactory() openflow.Factory {
function getFlowModCmd (line 98) | func getFlowModCmd(cmd openflow.FlowModCmd) uint16 {
FILE: openflow/of10/features.go
type FeaturesRequest (line 30) | type FeaturesRequest struct
method MarshalBinary (line 40) | func (r *FeaturesRequest) MarshalBinary() ([]byte, error) {
function NewFeaturesRequest (line 34) | func NewFeaturesRequest(xid uint32) openflow.FeaturesRequest {
type FeaturesReply (line 44) | type FeaturesReply struct
method DPID (line 54) | func (r FeaturesReply) DPID() uint64 {
method NumBuffers (line 58) | func (r FeaturesReply) NumBuffers() uint32 {
method NumTables (line 62) | func (r FeaturesReply) NumTables() uint8 {
method Capabilities (line 66) | func (r FeaturesReply) Capabilities() uint32 {
method Actions (line 70) | func (r FeaturesReply) Actions() uint32 {
method Ports (line 74) | func (r FeaturesReply) Ports() []openflow.Port {
method AuxID (line 78) | func (r FeaturesReply) AuxID() uint8 {
method UnmarshalBinary (line 83) | func (r *FeaturesReply) UnmarshalBinary(data []byte) error {
FILE: openflow/of10/flow_mod.go
type FlowMod (line 31) | type FlowMod struct
method Error (line 56) | func (r *FlowMod) Error() error {
method Cookie (line 60) | func (r *FlowMod) Cookie() uint64 {
method SetCookie (line 64) | func (r *FlowMod) SetCookie(cookie uint64) {
method CookieMask (line 68) | func (r *FlowMod) CookieMask() uint64 {
method SetCookieMask (line 73) | func (r *FlowMod) SetCookieMask(mask uint64) {
method TableID (line 77) | func (r *FlowMod) TableID() uint8 {
method SetTableID (line 82) | func (r *FlowMod) SetTableID(id uint8) {
method IdleTimeout (line 86) | func (r *FlowMod) IdleTimeout() uint16 {
method SetIdleTimeout (line 90) | func (r *FlowMod) SetIdleTimeout(timeout uint16) {
method HardTimeout (line 94) | func (r *FlowMod) HardTimeout() uint16 {
method SetHardTimeout (line 98) | func (r *FlowMod) SetHardTimeout(timeout uint16) {
method Priority (line 102) | func (r *FlowMod) Priority() uint16 {
method SetPriority (line 106) | func (r *FlowMod) SetPriority(priority uint16) {
method FlowMatch (line 110) | func (r *FlowMod) FlowMatch() openflow.Match {
method SetFlowMatch (line 114) | func (r *FlowMod) SetFlowMatch(match openflow.Match) {
method FlowInstruction (line 121) | func (r *FlowMod) FlowInstruction() openflow.Instruction {
method SetFlowInstruction (line 125) | func (r *FlowMod) SetFlowInstruction(inst openflow.Instruction) {
method OutPort (line 132) | func (r *FlowMod) OutPort() openflow.OutPort {
method SetOutPort (line 136) | func (r *FlowMod) SetOutPort(p openflow.OutPort) {
method MarshalBinary (line 140) | func (r *FlowMod) MarshalBinary() ([]byte, error) {
function NewFlowMod (line 44) | func NewFlowMod(xid uint32, cmd uint16) openflow.FlowMod {
FILE: openflow/of10/flow_removed.go
type FlowRemoved (line 30) | type FlowRemoved struct
method Cookie (line 43) | func (r FlowRemoved) Cookie() uint64 {
method Priority (line 47) | func (r FlowRemoved) Priority() uint16 {
method Reason (line 51) | func (r FlowRemoved) Reason() uint8 {
method TableID (line 55) | func (r FlowRemoved) TableID() uint8 {
method DurationSec (line 60) | func (r FlowRemoved) DurationSec() uint32 {
method DurationNanoSec (line 64) | func (r FlowRemoved) DurationNanoSec() uint32 {
method IdleTimeout (line 68) | func (r FlowRemoved) IdleTimeout() uint16 {
method HardTimeout (line 72) | func (r FlowRemoved) HardTimeout() uint16 {
method PacketCount (line 77) | func (r FlowRemoved) PacketCount() uint64 {
method ByteCount (line 81) | func (r FlowRemoved) ByteCount() uint64 {
method Match (line 85) | func (r FlowRemoved) Match() openflow.Match {
method UnmarshalBinary (line 89) | func (r *FlowRemoved) UnmarshalBinary(data []byte) error {
FILE: openflow/of10/flow_stats.go
type FlowStatsRequest (line 31) | type FlowStatsRequest struct
method Error (line 44) | func (r *FlowStatsRequest) Error() error {
method Cookie (line 48) | func (r *FlowStatsRequest) Cookie() uint64 {
method SetCookie (line 53) | func (r *FlowStatsRequest) SetCookie(cookie uint64) {
method CookieMask (line 57) | func (r *FlowStatsRequest) CookieMask() uint64 {
method SetCookieMask (line 62) | func (r *FlowStatsRequest) SetCookieMask(mask uint64) {
method Match (line 66) | func (r *FlowStatsRequest) Match() openflow.Match {
method SetMatch (line 70) | func (r *FlowStatsRequest) SetMatch(match openflow.Match) {
method TableID (line 77) | func (r *FlowStatsRequest) TableID() uint8 {
method SetTableID (line 82) | func (r *FlowStatsRequest) SetTableID(id uint8) {
method MarshalBinary (line 87) | func (r *FlowStatsRequest) MarshalBinary() ([]byte, error) {
function NewFlowStatsRequest (line 38) | func NewFlowStatsRequest(xid uint32) openflow.FlowStatsRequest {
FILE: openflow/of10/hello.go
function NewHello (line 28) | func NewHello(xid uint32) openflow.Hello {
FILE: openflow/of10/instruction.go
type Instruction (line 30) | type Instruction struct
method Error (line 35) | func (r *Instruction) Error() error {
method GotoTable (line 39) | func (r *Instruction) GotoTable(tableID uint8) {
method WriteAction (line 43) | func (r *Instruction) WriteAction(act openflow.Action) {
method ApplyAction (line 50) | func (r *Instruction) ApplyAction(act openflow.Action) {
method MarshalBinary (line 57) | func (r *Instruction) MarshalBinary() ([]byte, error) {
FILE: openflow/of10/match.go
type Wildcard (line 33) | type Wildcard struct
method MarshalBinary (line 66) | func (r *Wildcard) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 116) | func (r *Wildcard) UnmarshalBinary(data []byte) error {
function newWildcardAll (line 50) | func newWildcardAll() *Wildcard {
type Match (line 155) | type Match struct
method Error (line 182) | func (r *Match) Error() error {
method SetWildcardSrcPort (line 186) | func (r *Match) SetWildcardSrcPort() {
method SetSrcPort (line 191) | func (r *Match) SetSrcPort(p uint16) {
method SrcPort (line 207) | func (r *Match) SrcPort() (wildcard bool, port uint16) {
method SetWildcardDstPort (line 211) | func (r *Match) SetWildcardDstPort() {
method SetDstPort (line 216) | func (r *Match) SetDstPort(p uint16) {
method DstPort (line 232) | func (r *Match) DstPort() (wildcard bool, port uint16) {
method SetWildcardVLANID (line 236) | func (r *Match) SetWildcardVLANID() {
method SetVLANID (line 241) | func (r *Match) SetVLANID(id uint16) {
method VLANID (line 246) | func (r *Match) VLANID() (wildcard bool, vlanID uint16) {
method SetWildcardVLANPriority (line 250) | func (r *Match) SetWildcardVLANPriority() {
method SetVLANPriority (line 255) | func (r *Match) SetVLANPriority(p uint8) {
method VLANPriority (line 260) | func (r *Match) VLANPriority() (wildcard bool, priority uint8) {
method SetWildcardIPProtocol (line 264) | func (r *Match) SetWildcardIPProtocol() {
method SetIPProtocol (line 269) | func (r *Match) SetIPProtocol(p uint8) {
method IPProtocol (line 280) | func (r *Match) IPProtocol() (wildcard bool, protocol uint8) {
method SetWildcardInPort (line 284) | func (r *Match) SetWildcardInPort() {
method SetInPort (line 289) | func (r *Match) SetInPort(port openflow.InPort) {
method InPort (line 294) | func (r *Match) InPort() (wildcard bool, inport openflow.InPort) {
method SetWildcardSrcMAC (line 300) | func (r *Match) SetWildcardSrcMAC() {
method SetSrcMAC (line 305) | func (r *Match) SetSrcMAC(mac net.HardwareAddr) {
method SrcMAC (line 315) | func (r *Match) SrcMAC() (wildcard bool, mac net.HardwareAddr) {
method SetWildcardDstMAC (line 319) | func (r *Match) SetWildcardDstMAC() {
method SetDstMAC (line 324) | func (r *Match) SetDstMAC(mac net.HardwareAddr) {
method DstMAC (line 334) | func (r *Match) DstMAC() (wildcard bool, mac net.HardwareAddr) {
method SetSrcIP (line 338) | func (r *Match) SetSrcIP(ip *net.IPNet) {
method SrcIP (line 363) | func (r *Match) SrcIP() *net.IPNet {
method SetDstIP (line 373) | func (r *Match) SetDstIP(ip *net.IPNet) {
method DstIP (line 398) | func (r *Match) DstIP() *net.IPNet {
method SetWildcardEtherType (line 408) | func (r *Match) SetWildcardEtherType() {
method SetEtherType (line 413) | func (r *Match) SetEtherType(t uint16) {
method EtherType (line 418) | func (r *Match) EtherType() (wildcard bool, etherType uint16) {
method MarshalBinary (line 422) | func (r *Match) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 472) | func (r *Match) UnmarshalBinary(data []byte) error {
function NewMatch (line 172) | func NewMatch() openflow.Match {
FILE: openflow/of10/packet_in.go
type PacketIn (line 30) | type PacketIn struct
method BufferID (line 39) | func (r PacketIn) BufferID() uint32 {
method InPort (line 43) | func (r PacketIn) InPort() uint32 {
method Data (line 47) | func (r PacketIn) Data() []byte {
method Length (line 51) | func (r PacketIn) Length() uint16 {
method TableID (line 55) | func (r PacketIn) TableID() uint8 {
method Reason (line 60) | func (r PacketIn) Reason() uint8 {
method Cookie (line 64) | func (r PacketIn) Cookie() uint64 {
method UnmarshalBinary (line 69) | func (r *PacketIn) UnmarshalBinary(data []byte) error {
FILE: openflow/of10/packet_out.go
type PacketOut (line 30) | type PacketOut struct
method Error (line 44) | func (r *PacketOut) Error() error {
method InPort (line 48) | func (r *PacketOut) InPort() openflow.InPort {
method SetInPort (line 52) | func (r *PacketOut) SetInPort(port openflow.InPort) {
method Action (line 56) | func (r *PacketOut) Action() openflow.Action {
method SetAction (line 60) | func (r *PacketOut) SetAction(action openflow.Action) {
method Data (line 67) | func (r *PacketOut) Data() []byte {
method SetData (line 71) | func (r *PacketOut) SetData(data []byte) {
method MarshalBinary (line 78) | func (r *PacketOut) MarshalBinary() ([]byte, error) {
function NewPacketOut (line 38) | func NewPacketOut(xid uint32) openflow.PacketOut {
FILE: openflow/of10/port.go
type Port (line 32) | type Port struct
method Number (line 46) | func (r Port) Number() uint32 {
method MAC (line 50) | func (r Port) MAC() net.HardwareAddr {
method Name (line 54) | func (r Port) Name() string {
method IsPortDown (line 58) | func (r Port) IsPortDown() bool {
method IsLinkDown (line 66) | func (r Port) IsLinkDown() bool {
method IsCopper (line 74) | func (r Port) IsCopper() bool {
method IsFiber (line 78) | func (r Port) IsFiber() bool {
method IsAutoNego (line 82) | func (r Port) IsAutoNego() bool {
method Speed (line 86) | func (r Port) Speed() uint64 {
method UnmarshalBinary (line 107) | func (r *Port) UnmarshalBinary(data []byte) error {
FILE: openflow/of10/port_status.go
type PortStatus (line 28) | type PortStatus struct
method Reason (line 34) | func (r PortStatus) Reason() openflow.PortReason {
method Port (line 47) | func (r PortStatus) Port() openflow.Port {
method UnmarshalBinary (line 51) | func (r *PortStatus) UnmarshalBinary(data []byte) error {
FILE: openflow/of10/queue.go
type QueueGetConfigRequest (line 30) | type QueueGetConfigRequest struct
method Port (line 41) | func (r *QueueGetConfigRequest) Port() openflow.OutPort {
method SetPort (line 45) | func (r *QueueGetConfigRequest) SetPort(p openflow.OutPort) {
method MarshalBinary (line 49) | func (r *QueueGetConfigRequest) MarshalBinary() ([]byte, error) {
function NewQueueGetConfigRequest (line 35) | func NewQueueGetConfigRequest(xid uint32) openflow.QueueGetConfigRequest {
type QueueProperty (line 59) | type QueueProperty struct
method Type (line 69) | func (r *QueueProperty) Type() openflow.PropertyType {
method Length (line 73) | func (r *QueueProperty) Length() uint16 {
method Rate (line 77) | func (r *QueueProperty) Rate() (uint16, error) {
method Experimenter (line 85) | func (r *QueueProperty) Experimenter() (uint32, error) {
method Data (line 90) | func (r *QueueProperty) Data() []byte {
method UnmarshalBinary (line 94) | func (r *QueueProperty) UnmarshalBinary(data []byte) error {
function NewQueueProperty (line 65) | func NewQueueProperty() openflow.QueueProperty {
type Queue (line 112) | type Queue struct
method ID (line 118) | func (r *Queue) ID() uint32 {
method Port (line 122) | func (r *Queue) Port() uint32 {
method Length (line 127) | func (r *Queue) Length() uint16 {
method Property (line 131) | func (r *Queue) Property() []openflow.QueueProperty {
method UnmarshalBinary (line 135) | func (r *Queue) UnmarshalBinary(data []byte) error {
function NewQueue (line 156) | func NewQueue() openflow.Queue {
type QueueGetConfigReply (line 160) | type QueueGetConfigReply struct
method Port (line 166) | func (r *QueueGetConfigReply) Port() uint32 {
method Queue (line 170) | func (r *QueueGetConfigReply) Queue() []openflow.Queue {
method UnmarshalBinary (line 174) | func (r *QueueGetConfigReply) UnmarshalBinary(data []byte) error {
FILE: openflow/of13/action.go
type Action (line 33) | type Action struct
method MarshalBinary (line 99) | func (r *Action) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 133) | func (r *Action) UnmarshalBinary(data []byte) error {
function NewAction (line 37) | func NewAction() openflow.Action {
function marshalOutput (line 43) | func marshalOutput(p openflow.OutPort) ([]byte, error) {
function marshalMAC (line 72) | func marshalMAC(t uint8, mac net.HardwareAddr) ([]byte, error) {
FILE: openflow/of13/barrier.go
type BarrierRequest (line 28) | type BarrierRequest struct
method MarshalBinary (line 38) | func (r *BarrierRequest) MarshalBinary() ([]byte, error) {
function NewBarrierRequest (line 32) | func NewBarrierRequest(xid uint32) openflow.BarrierRequest {
type BarrierReply (line 42) | type BarrierReply struct
method UnmarshalBinary (line 46) | func (r *BarrierReply) UnmarshalBinary(data []byte) error {
FILE: openflow/of13/config.go
type Config (line 31) | type Config struct
method Flags (line 37) | func (r *Config) Flags() openflow.ConfigFlag {
method SetFlags (line 52) | func (r *Config) SetFlags(flags openflow.ConfigFlag) {
method MissSendLength (line 67) | func (r *Config) MissSendLength() uint16 {
method SetMissSendLength (line 71) | func (r *Config) SetMissSendLength(length uint16) {
method Error (line 75) | func (r *Config) Error() error {
type SetConfig (line 79) | type SetConfig struct
method MarshalBinary (line 94) | func (r *SetConfig) MarshalBinary() ([]byte, error) {
function NewSetConfig (line 84) | func NewSetConfig(xid uint32) openflow.SetConfig {
type GetConfigRequest (line 107) | type GetConfigRequest struct
method MarshalBinary (line 117) | func (r *GetConfigRequest) MarshalBinary() ([]byte, error) {
function NewGetConfigRequest (line 111) | func NewGetConfigRequest(xid uint32) openflow.GetConfigRequest {
type GetConfigReply (line 121) | type GetConfigReply struct
method UnmarshalBinary (line 126) | func (r *GetConfigReply) UnmarshalBinary(data []byte) error {
FILE: openflow/of13/const.go
constant OFPT_HELLO (line 26) | OFPT_HELLO uint8 = iota
constant OFPT_ERROR (line 27) | OFPT_ERROR
constant OFPT_ECHO_REQUEST (line 28) | OFPT_ECHO_REQUEST
constant OFPT_ECHO_REPLY (line 29) | OFPT_ECHO_REPLY
constant OFPT_EXPERIMENTER (line 30) | OFPT_EXPERIMENTER
constant OFPT_FEATURES_REQUEST (line 32) | OFPT_FEATURES_REQUEST
constant OFPT_FEATURES_REPLY (line 33) | OFPT_FEATURES_REPLY
constant OFPT_GET_CONFIG_REQUEST (line 34) | OFPT_GET_CONFIG_REQUEST
constant OFPT_GET_CONFIG_REPLY (line 35) | OFPT_GET_CONFIG_REPLY
constant OFPT_SET_CONFIG (line 36) | OFPT_SET_CONFIG
constant OFPT_PACKET_IN (line 38) | OFPT_PACKET_IN
constant OFPT_FLOW_REMOVED (line 39) | OFPT_FLOW_REMOVED
constant OFPT_PORT_STATUS (line 40) | OFPT_PORT_STATUS
constant OFPT_PACKET_OUT (line 42) | OFPT_PACKET_OUT
constant OFPT_FLOW_MOD (line 43) | OFPT_FLOW_MOD
constant OFPT_GROUP_MOD (line 44) | OFPT_GROUP_MOD
constant OFPT_PORT_MOD (line 45) | OFPT_PORT_MOD
constant OFPT_TABLE_MOD (line 46) | OFPT_TABLE_MOD
constant OFPT_MULTIPART_REQUEST (line 48) | OFPT_MULTIPART_REQUEST
constant OFPT_MULTIPART_REPLY (line 49) | OFPT_MULTIPART_REPLY
constant OFPT_BARRIER_REQUEST (line 51) | OFPT_BARRIER_REQUEST
constant OFPT_BARRIER_REPLY (line 52) | OFPT_BARRIER_REPLY
constant OFPT_QUEUE_GET_CONFIG_REQUEST (line 54) | OFPT_QUEUE_GET_CONFIG_REQUEST
constant OFPT_QUEUE_GET_CONFIG_REPLY (line 55) | OFPT_QUEUE_GET_CONFIG_REPLY
constant OFPT_ROLE_REQUEST (line 57) | OFPT_ROLE_REQUEST
constant OFPT_ROLE_REPLY (line 58) | OFPT_ROLE_REPLY
constant OFPT_GET_ASYNC_REQUEST (line 60) | OFPT_GET_ASYNC_REQUEST
constant OFPT_GET_ASYNC_REPLY (line 61) | OFPT_GET_ASYNC_REPLY
constant OFPT_SET_ASYNC (line 62) | OFPT_SET_ASYNC
constant OFPT_METER_MOD (line 64) | OFPT_METER_MOD
constant OFPAT_OUTPUT (line 68) | OFPAT_OUTPUT = 0
constant OFPAT_SET_FIELD (line 69) | OFPAT_SET_FIELD = 25
constant OFPP_MAX (line 74) | OFPP_MAX = 0xffffff00
constant OFPP_IN_PORT (line 76) | OFPP_IN_PORT = 0xfffffff8
constant OFPP_TABLE (line 77) | OFPP_TABLE = 0xfffffff9
constant OFPP_NORMAL (line 78) | OFPP_NORMAL = 0xfffffffa
constant OFPP_FLOOD (line 80) | OFPP_FLOOD = 0xfffffffb
constant OFPP_ALL (line 81) | OFPP_ALL = 0xfffffffc
constant OFPP_CONTROLLER (line 82) | OFPP_CONTROLLER = 0xfffffffd
constant OFPP_LOCAL (line 83) | OFPP_LOCAL = 0xfffffffe
constant OFPP_ANY (line 84) | OFPP_ANY = 0xffffffff
constant OFPXMT_OFB_IN_PORT (line 88) | OFPXMT_OFB_IN_PORT = iota
constant OFPXMT_OFB_IN_PHY_PORT (line 89) | OFPXMT_OFB_IN_PHY_PORT
constant OFPXMT_OFB_METADATA (line 90) | OFPXMT_OFB_METADATA
constant OFPXMT_OFB_ETH_DST (line 91) | OFPXMT_OFB_ETH_DST
constant OFPXMT_OFB_ETH_SRC (line 92) | OFPXMT_OFB_ETH_SRC
constant OFPXMT_OFB_ETH_TYPE (line 93) | OFPXMT_OFB_ETH_TYPE
constant OFPXMT_OFB_VLAN_VID (line 94) | OFPXMT_OFB_VLAN_VID
constant OFPXMT_OFB_VLAN_PCP (line 95) | OFPXMT_OFB_VLAN_PCP
constant OFPXMT_OFB_IP_DSCP (line 96) | OFPXMT_OFB_IP_DSCP
constant OFPXMT_OFB_IP_ECN (line 97) | OFPXMT_OFB_IP_ECN
constant OFPXMT_OFB_IP_PROTO (line 98) | OFPXMT_OFB_IP_PROTO
constant OFPXMT_OFB_IPV4_SRC (line 99) | OFPXMT_OFB_IPV4_SRC
constant OFPXMT_OFB_IPV4_DST (line 100) | OFPXMT_OFB_IPV4_DST
constant OFPXMT_OFB_TCP_SRC (line 101) | OFPXMT_OFB_TCP_SRC
constant OFPXMT_OFB_TCP_DST (line 102) | OFPXMT_OFB_TCP_DST
constant OFPXMT_OFB_UDP_SRC (line 103) | OFPXMT_OFB_UDP_SRC
constant OFPXMT_OFB_UDP_DST (line 104) | OFPXMT_OFB_UDP_DST
constant OFPXMT_OFB_SCTP_SRC (line 105) | OFPXMT_OFB_SCTP_SRC
constant OFPXMT_OFB_SCTP_DST (line 106) | OFPXMT_OFB_SCTP_DST
constant OFPXMT_OFB_ICMPV4_TYPE (line 107) | OFPXMT_OFB_ICMPV4_TYPE
constant OFPXMT_OFB_ICMPV4_CODE (line 108) | OFPXMT_OFB_ICMPV4_CODE
constant OFPXMT_OFB_ARP_OP (line 109) | OFPXMT_OFB_ARP_OP
constant OFPXMT_OFB_ARP_SPA (line 110) | OFPXMT_OFB_ARP_SPA
constant OFPXMT_OFB_ARP_TPA (line 111) | OFPXMT_OFB_ARP_TPA
constant OFPXMT_OFB_ARP_SHA (line 112) | OFPXMT_OFB_ARP_SHA
constant OFPXMT_OFB_ARP_THA (line 113) | OFPXMT_OFB_ARP_THA
constant OFPXMT_OFB_IPV6_SRC (line 114) | OFPXMT_OFB_IPV6_SRC
constant OFPXMT_OFB_IPV6_DST (line 115) | OFPXMT_OFB_IPV6_DST
constant OFPXMT_OFB_IPV6_FLABEL (line 116) | OFPXMT_OFB_IPV6_FLABEL
constant OFPXMT_OFB_ICMPV6_TYPE (line 117) | OFPXMT_OFB_ICMPV6_TYPE
constant OFPXMT_OFB_ICMPV6_CODE (line 118) | OFPXMT_OFB_ICMPV6_CODE
constant OFPXMT_OFB_IPV6_ND_TARGET (line 119) | OFPXMT_OFB_IPV6_ND_TARGET
constant OFPXMT_OFB_IPV6_ND_SLL (line 120) | OFPXMT_OFB_IPV6_ND_SLL
constant OFPXMT_OFB_IPV6_ND_TLL (line 121) | OFPXMT_OFB_IPV6_ND_TLL
constant OFPXMT_OFB_MPLS_LABEL (line 122) | OFPXMT_OFB_MPLS_LABEL
constant OFPXMT_OFB_MPLS_TC (line 123) | OFPXMT_OFB_MPLS_TC
constant OFPXMT_OFP_MPLS_BOS (line 124) | OFPXMT_OFP_MPLS_BOS
constant OFPXMT_OFB_PBB_ISID (line 125) | OFPXMT_OFB_PBB_ISID
constant OFPXMT_OFB_TUNNEL_ID (line 126) | OFPXMT_OFB_TUNNEL_ID
constant OFPXMT_OFB_IPV6_EXTHDR (line 127) | OFPXMT_OFB_IPV6_EXTHDR
constant OFPMT_STANDARD (line 131) | OFPMT_STANDARD = 0
constant OFPMT_OXM (line 132) | OFPMT_OXM = 1
constant OFPFC_ADD (line 136) | OFPFC_ADD = 0
constant OFPFC_MODIFY (line 137) | OFPFC_MODIFY = 1
constant OFPFC_MODIFY_STRICT (line 138) | OFPFC_MODIFY_STRICT = 2
constant OFPFC_DELETE (line 139) | OFPFC_DELETE = 3
constant OFPFC_DELETE_STRICT (line 140) | OFPFC_DELETE_STRICT = 4
constant OFP_NO_BUFFER (line 144) | OFP_NO_BUFFER = 0xffffffff
constant OFPFF_SEND_FLOW_REM (line 148) | OFPFF_SEND_FLOW_REM = 1 << 0
constant OFPFF_CHECK_OVERLAP (line 149) | OFPFF_CHECK_OVERLAP = 1 << 1
constant OFPFF_RESET_COUNTS (line 150) | OFPFF_RESET_COUNTS = 1 << 2
constant OFPFF_NO_PKT_COUNTS (line 151) | OFPFF_NO_PKT_COUNTS = 1 << 3
constant OFPFF_NO_BYT_COUNTS (line 152) | OFPFF_NO_BYT_COUNTS = 1 << 4
constant OFPPC_PORT_DOWN (line 156) | OFPPC_PORT_DOWN = 1 << 0
constant OFPPC_NO_RECV (line 157) | OFPPC_NO_RECV = 1 << 2
constant OFPPC_NO_FWD (line 158) | OFPPC_NO_FWD = 1 << 5
constant OFPPC_NO_PACKET_IN (line 159) | OFPPC_NO_PACKET_IN = 1 << 6
constant OFPPS_LINK_DOWN (line 163) | OFPPS_LINK_DOWN = 1 << 0
constant OFPPS_BLOCKED (line 164) | OFPPS_BLOCKED = 1 << 1
constant OFPPS_LIVE (line 165) | OFPPS_LIVE = 1 << 2
constant OFPPF_10MB_HD (line 169) | OFPPF_10MB_HD = 1 << 0
constant OFPPF_10MB_FD (line 170) | OFPPF_10MB_FD = 1 << 1
constant OFPPF_100MB_HD (line 171) | OFPPF_100MB_HD = 1 << 2
constant OFPPF_100MB_FD (line 172) | OFPPF_100MB_FD = 1 << 3
constant OFPPF_1GB_HD (line 173) | OFPPF_1GB_HD = 1 << 4
constant OFPPF_1GB_FD (line 174) | OFPPF_1GB_FD = 1 << 5
constant OFPPF_10GB_FD (line 175) | OFPPF_10GB_FD = 1 << 6
constant OFPPF_40GB_FD (line 176) | OFPPF_40GB_FD = 1 << 7
constant OFPPF_100GB_FD (line 177) | OFPPF_100GB_FD = 1 << 8
constant OFPPF_1TB_FD (line 178) | OFPPF_1TB_FD = 1 << 9
constant OFPPF_OTHER (line 179) | OFPPF_OTHER = 1 << 10
constant OFPPF_COPPER (line 180) | OFPPF_COPPER = 1 << 11
constant OFPPF_FIBER (line 181) | OFPPF_FIBER = 1 << 12
constant OFPPF_AUTONEG (line 182) | OFPPF_AUTONEG = 1 << 13
constant OFPPF_PAUSE (line 183) | OFPPF_PAUSE = 1 << 14
constant OFPPF_PAUSE_ASYM (line 184) | OFPPF_PAUSE_ASYM = 1 << 15
constant OFPMP_DESC (line 191) | OFPMP_DESC = 0
constant OFPMP_FLOW (line 195) | OFPMP_FLOW = 1
constant OFPMP_AGGREGATE (line 199) | OFPMP_AGGREGATE = 2
constant OFPMP_TABLE (line 203) | OFPMP_TABLE = 3
constant OFPMP_PORT_STATS (line 207) | OFPMP_PORT_STATS = 4
constant OFPMP_QUEUE (line 211) | OFPMP_QUEUE = 5
constant OFPMP_GROUP (line 215) | OFPMP_GROUP = 6
constant OFPMP_GROUP_DESC (line 219) | OFPMP_GROUP_DESC = 7
constant OFPMP_GROUP_FEATURES (line 223) | OFPMP_GROUP_FEATURES = 8
constant OFPMP_METER (line 227) | OFPMP_METER = 9
constant OFPMP_METER_CONFIG (line 231) | OFPMP_METER_CONFIG = 10
constant OFPMP_METER_FEATURES (line 235) | OFPMP_METER_FEATURES = 11
constant OFPMP_TABLE_FEATURES (line 242) | OFPMP_TABLE_FEATURES = 12
constant OFPMP_PORT_DESC (line 246) | OFPMP_PORT_DESC = 13
constant OFPMP_EXPERIMENTER (line 251) | OFPMP_EXPERIMENTER = 0xffff
constant OFPG_ANY (line 255) | OFPG_ANY = 0xffffffff
constant OFPC_FRAG_NORMAL (line 259) | OFPC_FRAG_NORMAL = 0
constant OFPC_FRAG_DROP (line 260) | OFPC_FRAG_DROP = 1 << 0
constant OFPC_FRAG_REASM (line 261) | OFPC_FRAG_REASM = 1 << 1
constant OFPC_FRAG_MASK (line 262) | OFPC_FRAG_MASK = 3
constant OFPPR_ADD (line 266) | OFPPR_ADD = 0
constant OFPPR_DELETE (line 267) | OFPPR_DELETE = 1
constant OFPPR_MODIFY (line 268) | OFPPR_MODIFY = 2
constant OFPIT_GOTO_TABLE (line 272) | OFPIT_GOTO_TABLE = 1
constant OFPIT_WRITE_METADATA (line 273) | OFPIT_WRITE_METADATA = 2
constant OFPIT_WRITE_ACTIONS (line 274) | OFPIT_WRITE_ACTIONS = 3
constant OFPIT_APPLY_ACTIONS (line 275) | OFPIT_APPLY_ACTIONS = 4
constant OFPIT_CLEAR_ACTIONS (line 276) | OFPIT_CLEAR_ACTIONS = 5
constant OFPIT_METER (line 277) | OFPIT_METER = 6
constant OFPIT_EXPERIMENTER (line 278) | OFPIT_EXPERIMENTER = 0xFFFF
FILE: openflow/of13/echo.go
function NewEchoRequest (line 28) | func NewEchoRequest(xid uint32) openflow.EchoRequest {
function NewEchoReply (line 34) | func NewEchoReply(xid uint32) openflow.EchoReply {
FILE: openflow/of13/factory.go
type Factory (line 32) | type Factory struct
method ProtocolVersion (line 40) | func (r *Factory) ProtocolVersion() uint8 {
method getTransactionID (line 44) | func (r *Factory) getTransactionID() uint32 {
method NewHello (line 49) | func (r *Factory) NewHello() (openflow.Hello, error) {
method NewEchoRequest (line 53) | func (r *Factory) NewEchoRequest() (openflow.EchoRequest, error) {
method NewEchoReply (line 57) | func (r *Factory) NewEchoReply() (openflow.EchoReply, error) {
method NewAction (line 61) | func (r *Factory) NewAction() (openflow.Action, error) {
method NewMatch (line 65) | func (r *Factory) NewMatch() (openflow.Match, error) {
method NewBarrierRequest (line 69) | func (r *Factory) NewBarrierRequest() (openflow.BarrierRequest, error) {
method NewBarrierReply (line 73) | func (r *Factory) NewBarrierReply() (openflow.BarrierReply, error) {
method NewSetConfig (line 77) | func (r *Factory) NewSetConfig() (openflow.SetConfig, error) {
method NewGetConfigRequest (line 81) | func (r *Factory) NewGetConfigRequest() (openflow.GetConfigRequest, er...
method NewGetConfigReply (line 85) | func (r *Factory) NewGetConfigReply() (openflow.GetConfigReply, error) {
method NewFeaturesRequest (line 89) | func (r *Factory) NewFeaturesRequest() (openflow.FeaturesRequest, erro...
method NewFeaturesReply (line 93) | func (r *Factory) NewFeaturesReply() (openflow.FeaturesReply, error) {
method NewFlowMod (line 113) | func (r *Factory) NewFlowMod(cmd openflow.FlowModCmd) (openflow.FlowMo...
method NewFlowRemoved (line 117) | func (r *Factory) NewFlowRemoved() (openflow.FlowRemoved, error) {
method NewPacketIn (line 121) | func (r *Factory) NewPacketIn() (openflow.PacketIn, error) {
method NewPacketOut (line 125) | func (r *Factory) NewPacketOut() (openflow.PacketOut, error) {
method NewPortStatus (line 129) | func (r *Factory) NewPortStatus() (openflow.PortStatus, error) {
method NewDescRequest (line 133) | func (r *Factory) NewDescRequest() (openflow.DescRequest, error) {
method NewDescReply (line 137) | func (r *Factory) NewDescReply() (openflow.DescReply, error) {
method NewFlowStatsRequest (line 141) | func (r *Factory) NewFlowStatsRequest() (openflow.FlowStatsRequest, er...
method NewPortDescRequest (line 147) | func (r *Factory) NewPortDescRequest() (openflow.PortDescRequest, erro...
method NewPortDescReply (line 151) | func (r *Factory) NewPortDescReply() (openflow.PortDescReply, error) {
method NewTableFeaturesRequest (line 155) | func (r *Factory) NewTableFeaturesRequest() (openflow.TableFeaturesReq...
method NewError (line 159) | func (r *Factory) NewError() (openflow.Error, error) {
method NewInstruction (line 165) | func (r *Factory) NewInstruction() (openflow.Instruction, error) {
method NewQueueGetConfigRequest (line 169) | func (r *Factory) NewQueueGetConfigRequest() (openflow.QueueGetConfigR...
function NewFactory (line 36) | func NewFactory() openflow.Factory {
function getFlowModCmd (line 97) | func getFlowModCmd(cmd openflow.FlowModCmd) uint8 {
FILE: openflow/of13/features.go
type FeaturesRequest (line 30) | type FeaturesRequest struct
method MarshalBinary (line 40) | func (r *FeaturesRequest) MarshalBinary() ([]byte, error) {
function NewFeaturesRequest (line 34) | func NewFeaturesRequest(xid uint32) openflow.FeaturesRequest {
type FeaturesReply (line 44) | type FeaturesReply struct
method DPID (line 53) | func (r FeaturesReply) DPID() uint64 {
method NumBuffers (line 57) | func (r FeaturesReply) NumBuffers() uint32 {
method NumTables (line 61) | func (r FeaturesReply) NumTables() uint8 {
method Capabilities (line 65) | func (r FeaturesReply) Capabilities() uint32 {
method Actions (line 69) | func (r FeaturesReply) Actions() uint32 {
method Ports (line 74) | func (r FeaturesReply) Ports() []openflow.Port {
method AuxID (line 79) | func (r FeaturesReply) AuxID() uint8 {
method UnmarshalBinary (line 83) | func (r *FeaturesReply) UnmarshalBinary(data []byte) error {
FILE: openflow/of13/flow_mod.go
type FlowMod (line 31) | type FlowMod struct
method Error (line 58) | func (r *FlowMod) Error() error {
method Cookie (line 62) | func (r *FlowMod) Cookie() uint64 {
method SetCookie (line 66) | func (r *FlowMod) SetCookie(cookie uint64) {
method CookieMask (line 70) | func (r *FlowMod) CookieMask() uint64 {
method SetCookieMask (line 74) | func (r *FlowMod) SetCookieMask(mask uint64) {
method TableID (line 78) | func (r *FlowMod) TableID() uint8 {
method SetTableID (line 82) | func (r *FlowMod) SetTableID(id uint8) {
method IdleTimeout (line 86) | func (r *FlowMod) IdleTimeout() uint16 {
method SetIdleTimeout (line 90) | func (r *FlowMod) SetIdleTimeout(timeout uint16) {
method HardTimeout (line 94) | func (r *FlowMod) HardTimeout() uint16 {
method SetHardTimeout (line 98) | func (r *FlowMod) SetHardTimeout(timeout uint16) {
method Priority (line 102) | func (r *FlowMod) Priority() uint16 {
method SetPriority (line 106) | func (r *FlowMod) SetPriority(priority uint16) {
method FlowMatch (line 110) | func (r *FlowMod) FlowMatch() openflow.Match {
method SetFlowMatch (line 114) | func (r *FlowMod) SetFlowMatch(match openflow.Match) {
method FlowInstruction (line 121) | func (r *FlowMod) FlowInstruction() openflow.Instruction {
method SetFlowInstruction (line 125) | func (r *FlowMod) SetFlowInstruction(inst openflow.Instruction) {
method OutPort (line 132) | func (r *FlowMod) OutPort() openflow.OutPort {
method SetOutPort (line 136) | func (r *FlowMod) SetOutPort(p openflow.OutPort) {
method MarshalBinary (line 140) | func (r *FlowMod) MarshalBinary() ([]byte, error) {
function NewFlowMod (line 46) | func NewFlowMod(xid uint32, cmd uint8) openflow.FlowMod {
FILE: openflow/of13/flow_removed.go
type FlowRemoved (line 30) | type FlowRemoved struct
method Cookie (line 45) | func (r FlowRemoved) Cookie() uint64 {
method Priority (line 49) | func (r FlowRemoved) Priority() uint16 {
method Reason (line 53) | func (r FlowRemoved) Reason() uint8 {
method TableID (line 57) | func (r FlowRemoved) TableID() uint8 {
method DurationSec (line 61) | func (r FlowRemoved) DurationSec() uint32 {
method DurationNanoSec (line 65) | func (r FlowRemoved) DurationNanoSec() uint32 {
method IdleTimeout (line 69) | func (r FlowRemoved) IdleTimeout() uint16 {
method HardTimeout (line 73) | func (r FlowRemoved) HardTimeout() uint16 {
method PacketCount (line 77) | func (r FlowRemoved) PacketCount() uint64 {
method ByteCount (line 81) | func (r FlowRemoved) ByteCount() uint64 {
method Match (line 85) | func (r FlowRemoved) Match() openflow.Match {
method UnmarshalBinary (line 89) | func (r *FlowRemoved) UnmarshalBinary(data []byte) error {
FILE: openflow/of13/hello.go
function NewHello (line 28) | func NewHello(xid uint32) openflow.Hello {
FILE: openflow/of13/instruction.go
type Instruction (line 32) | type Instruction struct
method Error (line 95) | func (r *Instruction) Error() error {
method GotoTable (line 99) | func (r *Instruction) GotoTable(tableID uint8) {
method WriteAction (line 103) | func (r *Instruction) WriteAction(act openflow.Action) {
method ApplyAction (line 110) | func (r *Instruction) ApplyAction(act openflow.Action) {
method MarshalBinary (line 117) | func (r *Instruction) MarshalBinary() ([]byte, error) {
type gotoTable (line 37) | type gotoTable struct
method MarshalBinary (line 41) | func (r *gotoTable) MarshalBinary() ([]byte, error) {
type writeAction (line 51) | type writeAction struct
method MarshalBinary (line 55) | func (r *writeAction) MarshalBinary() ([]byte, error) {
type applyAction (line 73) | type applyAction struct
method MarshalBinary (line 77) | func (r *applyAction) MarshalBinary() ([]byte, error) {
FILE: openflow/of13/match.go
type Match (line 36) | type Match struct
method Error (line 49) | func (r *Match) Error() error {
method SetWildcardSrcPort (line 53) | func (r *Match) SetWildcardSrcPort() {
method SetSrcPort (line 61) | func (r *Match) SetSrcPort(p uint16) {
method SrcPort (line 97) | func (r *Match) SrcPort() (wildcard bool, port uint16) {
method SetWildcardDstPort (line 114) | func (r *Match) SetWildcardDstPort() {
method SetDstPort (line 122) | func (r *Match) SetDstPort(p uint16) {
method DstPort (line 158) | func (r *Match) DstPort() (wildcard bool, port uint16) {
method SetWildcardVLANID (line 175) | func (r *Match) SetWildcardVLANID() {
method SetVLANID (line 182) | func (r *Match) SetVLANID(id uint16) {
method VLANID (line 189) | func (r *Match) VLANID() (wildcard bool, vlanID uint16) {
method SetWildcardVLANPriority (line 201) | func (r *Match) SetWildcardVLANPriority() {
method SetVLANPriority (line 208) | func (r *Match) SetVLANPriority(p uint8) {
method VLANPriority (line 215) | func (r *Match) VLANPriority() (wildcard bool, priority uint8) {
method SetWildcardIPProtocol (line 227) | func (r *Match) SetWildcardIPProtocol() {
method SetIPProtocol (line 234) | func (r *Match) SetIPProtocol(p uint8) {
method IPProtocol (line 252) | func (r *Match) IPProtocol() (wildcard bool, protocol uint8) {
method SetWildcardInPort (line 264) | func (r *Match) SetWildcardInPort() {
method SetInPort (line 271) | func (r *Match) SetInPort(port openflow.InPort) {
method InPort (line 278) | func (r *Match) InPort() (wildcard bool, inport openflow.InPort) {
method SetWildcardSrcMAC (line 292) | func (r *Match) SetWildcardSrcMAC() {
method SetSrcMAC (line 299) | func (r *Match) SetSrcMAC(mac net.HardwareAddr) {
method SrcMAC (line 313) | func (r *Match) SrcMAC() (wildcard bool, mac net.HardwareAddr) {
method SetWildcardDstMAC (line 325) | func (r *Match) SetWildcardDstMAC() {
method SetDstMAC (line 332) | func (r *Match) SetDstMAC(mac net.HardwareAddr) {
method DstMAC (line 346) | func (r *Match) DstMAC() (wildcard bool, mac net.HardwareAddr) {
method SetSrcIP (line 358) | func (r *Match) SetSrcIP(ip *net.IPNet) {
method SrcIP (line 384) | func (r *Match) SrcIP() *net.IPNet {
method SetDstIP (line 399) | func (r *Match) SetDstIP(ip *net.IPNet) {
method DstIP (line 425) | func (r *Match) DstIP() *net.IPNet {
method SetWildcardEtherType (line 440) | func (r *Match) SetWildcardEtherType() {
method SetEtherType (line 447) | func (r *Match) SetEtherType(t uint16) {
method EtherType (line 454) | func (r *Match) EtherType() (wildcard bool, etherType uint16) {
method MarshalBinary (line 562) | func (r *Match) MarshalBinary() ([]byte, error) {
method unmarshalUint8TLV (line 590) | func (r *Match) unmarshalUint8TLV(field uint8, data []byte) error {
method unmarshalUint16TLV (line 599) | func (r *Match) unmarshalUint16TLV(field uint8, data []byte) error {
method unmarshalUint32TLV (line 609) | func (r *Match) unmarshalUint32TLV(field uint8, data []byte) error {
method unmarshalHardwareAddrTLV (line 619) | func (r *Match) unmarshalHardwareAddrTLV(field uint8, data []byte) err...
method unmarshalIPNetTLV (line 630) | func (r *Match) unmarshalIPNetTLV(field uint8, hasmask uint8, data []b...
method unmarshalTLV (line 654) | func (r *Match) unmarshalTLV(data []byte) error {
method UnmarshalBinary (line 734) | func (r *Match) UnmarshalBinary(data []byte) error {
function NewMatch (line 43) | func NewMatch() openflow.Match {
function marshalIPNetTLV (line 466) | func marshalIPNetTLV(field uint8, ip *net.IPNet) ([]byte, error) {
function marshalHardwareAddrTLV (line 480) | func marshalHardwareAddrTLV(field uint8, mac net.HardwareAddr) ([]byte, ...
function marshalUint8TLV (line 489) | func marshalUint8TLV(field uint8, v uint8) ([]byte, error) {
function marshalUint16TLV (line 498) | func marshalUint16TLV(field uint8, v uint16) ([]byte, error) {
function marshalUint32TLV (line 507) | func marshalUint32TLV(field uint8, v uint32) ([]byte, error) {
function marshalTLV (line 516) | func marshalTLV(id uint, v interface{}) ([]byte, error) {
FILE: openflow/of13/multipart_description.go
type DescRequest (line 31) | type DescRequest struct
method MarshalBinary (line 41) | func (r *DescRequest) MarshalBinary() ([]byte, error) {
function NewDescRequest (line 35) | func NewDescRequest(xid uint32) openflow.DescRequest {
type DescReply (line 51) | type DescReply struct
method Manufacturer (line 60) | func (r DescReply) Manufacturer() string {
method Hardware (line 64) | func (r DescReply) Hardware() string {
method Software (line 68) | func (r DescReply) Software() string {
method Serial (line 72) | func (r DescReply) Serial() string {
method Description (line 76) | func (r DescReply) Description() string {
method UnmarshalBinary (line 80) | func (r *DescReply) UnmarshalBinary(data []byte) error {
FILE: openflow/of13/multipart_flow_stats.go
type FlowStatsRequest (line 31) | type FlowStatsRequest struct
method Error (line 45) | func (r *FlowStatsRequest) Error() error {
method Cookie (line 49) | func (r *FlowStatsRequest) Cookie() uint64 {
method SetCookie (line 53) | func (r *FlowStatsRequest) SetCookie(cookie uint64) {
method CookieMask (line 57) | func (r *FlowStatsRequest) CookieMask() uint64 {
method SetCookieMask (line 61) | func (r *FlowStatsRequest) SetCookieMask(mask uint64) {
method Match (line 65) | func (r *FlowStatsRequest) Match() openflow.Match {
method SetMatch (line 69) | func (r *FlowStatsRequest) SetMatch(match openflow.Match) {
method TableID (line 76) | func (r *FlowStatsRequest) TableID() uint8 {
method SetTableID (line 81) | func (r *FlowStatsRequest) SetTableID(id uint8) {
method MarshalBinary (line 85) | func (r *FlowStatsRequest) MarshalBinary() ([]byte, error) {
function NewFlowStatsRequest (line 39) | func NewFlowStatsRequest(xid uint32) openflow.FlowStatsRequest {
FILE: openflow/of13/multipart_port_description.go
type PortDescRequest (line 30) | type PortDescRequest struct
method MarshalBinary (line 40) | func (r *PortDescRequest) MarshalBinary() ([]byte, error) {
function NewPortDescRequest (line 34) | func NewPortDescRequest(xid uint32) openflow.PortDescRequest {
type PortDescReply (line 50) | type PortDescReply struct
method Ports (line 55) | func (r PortDescReply) Ports() []openflow.Port {
method UnmarshalBinary (line 59) | func (r *PortDescReply) UnmarshalBinary(data []byte) error {
FILE: openflow/of13/multipart_table_features.go
type TableFeaturesRequest (line 30) | type TableFeaturesRequest struct
method MarshalBinary (line 40) | func (r *TableFeaturesRequest) MarshalBinary() ([]byte, error) {
function NewTableFeaturesRequest (line 34) | func NewTableFeaturesRequest(xid uint32) openflow.TableFeaturesRequest {
FILE: openflow/of13/packet_in.go
type PacketIn (line 30) | type PacketIn struct
method BufferID (line 41) | func (r PacketIn) BufferID() uint32 {
method InPort (line 45) | func (r PacketIn) InPort() uint32 {
method Data (line 49) | func (r PacketIn) Data() []byte {
method Length (line 53) | func (r PacketIn) Length() uint16 {
method TableID (line 57) | func (r PacketIn) TableID() uint8 {
method Reason (line 61) | func (r PacketIn) Reason() uint8 {
method Cookie (line 65) | func (r PacketIn) Cookie() uint64 {
method UnmarshalBinary (line 69) | func (r *PacketIn) UnmarshalBinary(data []byte) error {
FILE: openflow/of13/packet_out.go
type PacketOut (line 30) | type PacketOut struct
method Error (line 44) | func (r *PacketOut) Error() error {
method InPort (line 48) | func (r *PacketOut) InPort() openflow.InPort {
method SetInPort (line 52) | func (r *PacketOut) SetInPort(port openflow.InPort) {
method Action (line 56) | func (r *PacketOut) Action() openflow.Action {
method SetAction (line 60) | func (r *PacketOut) SetAction(action openflow.Action) {
method Data (line 67) | func (r *PacketOut) Data() []byte {
method SetData (line 71) | func (r *PacketOut) SetData(data []byte) {
method MarshalBinary (line 78) | func (r *PacketOut) MarshalBinary() ([]byte, error) {
function NewPacketOut (line 38) | func NewPacketOut(xid uint32) openflow.PacketOut {
FILE: openflow/of13/port.go
type Port (line 32) | type Port struct
method Number (line 47) | func (r Port) Number() uint32 {
method MAC (line 51) | func (r Port) MAC() net.HardwareAddr {
method Name (line 55) | func (r Port) Name() string {
method IsPortDown (line 59) | func (r Port) IsPortDown() bool {
method IsLinkDown (line 67) | func (r Port) IsLinkDown() bool {
method IsCopper (line 75) | func (r Port) IsCopper() bool {
method IsFiber (line 79) | func (r Port) IsFiber() bool {
method IsAutoNego (line 83) | func (r Port) IsAutoNego() bool {
method Speed (line 87) | func (r *Port) Speed() uint64 {
method UnmarshalBinary (line 114) | func (r *Port) UnmarshalBinary(data []byte) error {
FILE: openflow/of13/port_status.go
type PortStatus (line 28) | type PortStatus struct
method Reason (line 34) | func (r PortStatus) Reason() openflow.PortReason {
method Port (line 47) | func (r PortStatus) Port() openflow.Port {
method UnmarshalBinary (line 51) | func (r *PortStatus) UnmarshalBinary(data []byte) error {
FILE: openflow/of13/queue.go
type QueueGetConfigRequest (line 30) | type QueueGetConfigRequest struct
method Port (line 41) | func (r *QueueGetConfigRequest) Port() openflow.OutPort {
method SetPort (line 45) | func (r *QueueGetConfigRequest) SetPort(p openflow.OutPort) {
method MarshalBinary (line 49) | func (r *QueueGetConfigRequest) MarshalBinary() ([]byte, error) {
function NewQueueGetConfigRequest (line 35) | func NewQueueGetConfigRequest(xid uint32) openflow.QueueGetConfigRequest {
type QueueProperty (line 63) | type QueueProperty struct
method Type (line 75) | func (r *QueueProperty) Type() openflow.PropertyType {
method Length (line 79) | func (r *QueueProperty) Length() uint16 {
method Rate (line 83) | func (r *QueueProperty) Rate() (uint16, error) {
method Experimenter (line 90) | func (r *QueueProperty) Experimenter() (uint32, error) {
method Data (line 97) | func (r *QueueProperty) Data() []byte {
method UnmarshalBinary (line 101) | func (r *QueueProperty) UnmarshalBinary(data []byte) error {
function NewQueueProperty (line 71) | func NewQueueProperty() openflow.QueueProperty {
type Queue (line 125) | type Queue struct
method ID (line 132) | func (r *Queue) ID() uint32 {
method Port (line 136) | func (r *Queue) Port() uint32 {
method Length (line 140) | func (r *Queue) Length() uint16 {
method Property (line 144) | func (r *Queue) Property() []openflow.QueueProperty {
method UnmarshalBinary (line 148) | func (r *Queue) UnmarshalBinary(data []byte) error {
function NewQueue (line 170) | func NewQueue() openflow.Queue {
type QueueGetConfigReply (line 174) | type QueueGetConfigReply struct
method Port (line 180) | func (r *QueueGetConfigReply) Port() uint32 {
method Queue (line 184) | func (r *QueueGetConfigReply) Queue() []openflow.Queue {
method UnmarshalBinary (line 188) | func (r *QueueGetConfigReply) UnmarshalBinary(data []byte) error {
FILE: openflow/packet_in.go
type PacketIn (line 28) | type PacketIn interface
FILE: openflow/packet_out.go
type PacketOut (line 28) | type PacketOut interface
FILE: openflow/port.go
constant table (line 31) | table = iota
constant flood (line 32) | flood
constant all (line 33) | all
constant controller (line 34) | controller
constant inport (line 35) | inport
constant none (line 36) | none
type OutPort (line 39) | type OutPort struct
method SetTable (line 51) | func (r *OutPort) SetTable() {
method IsTable (line 55) | func (r *OutPort) IsTable() bool {
method SetFlood (line 59) | func (r *OutPort) SetFlood() {
method IsFlood (line 63) | func (r *OutPort) IsFlood() bool {
method SetAll (line 67) | func (r *OutPort) SetAll() {
method IsAll (line 71) | func (r *OutPort) IsAll() bool {
method SetController (line 75) | func (r *OutPort) SetController() {
method IsController (line 79) | func (r *OutPort) IsController() bool {
method SetInPort (line 83) | func (r *OutPort) SetInPort() {
method IsInPort (line 87) | func (r *OutPort) IsInPort() bool {
method SetNone (line 91) | func (r *OutPort) SetNone() {
method IsNone (line 95) | func (r *OutPort) IsNone() bool {
method SetValue (line 99) | func (r *OutPort) SetValue(port uint32) {
method Value (line 104) | func (r *OutPort) Value() uint32 {
method String (line 108) | func (r OutPort) String() string {
function NewOutPort (line 45) | func NewOutPort() OutPort {
type InPort (line 112) | type InPort struct
method SetValue (line 123) | func (r *InPort) SetValue(port uint32) {
method SetController (line 128) | func (r *InPort) SetController() {
method IsController (line 133) | func (r *InPort) IsController() bool {
method Value (line 137) | func (r *InPort) Value() uint32 {
function NewInPort (line 117) | func NewInPort() InPort {
type Port (line 141) | type Port interface
FILE: openflow/port_description.go
type PortDescRequest (line 28) | type PortDescRequest interface
type PortDescReply (line 33) | type PortDescReply interface
FILE: openflow/port_status.go
type PortReason (line 28) | type PortReason
constant PortAdded (line 31) | PortAdded PortReason = iota
constant PortDeleted (line 32) | PortDeleted
constant PortModified (line 33) | PortModified
type PortStatus (line 36) | type PortStatus interface
FILE: openflow/queue.go
type PropertyType (line 28) | type PropertyType
constant OFPQT_NONE (line 31) | OFPQT_NONE PropertyType = iota
constant OFPQT_MIN_RATE (line 32) | OFPQT_MIN_RATE
constant OFPQT_MAX_RATE (line 33) | OFPQT_MAX_RATE
constant OFPQT_EXPERIMENTER (line 34) | OFPQT_EXPERIMENTER = 0xffff
type Queue (line 37) | type Queue interface
type QueueProperty (line 45) | type QueueProperty interface
type QueueGetConfigRequest (line 54) | type QueueGetConfigRequest interface
type QueueGetConfigReply (line 61) | type QueueGetConfigReply interface
FILE: openflow/table_features.go
type TableFeaturesRequest (line 28) | type TableFeaturesRequest interface
FILE: openflow/transceiver/stream.go
type Stream (line 33) | type Stream struct
method RemoteAddr (line 85) | func (r *Stream) RemoteAddr() net.Addr {
method SetReadTimeout (line 99) | func (r *Stream) SetReadTimeout(t time.Duration) {
method GetReadTimeout (line 107) | func (r *Stream) GetReadTimeout() time.Duration {
method SetWriteTimeout (line 115) | func (r *Stream) SetWriteTimeout(t time.Duration) {
method GetWriteTimeout (line 123) | func (r *Stream) GetWriteTimeout() time.Duration {
method Read (line 131) | func (r *Stream) Read(p []byte) (n int, err error) {
method setReadDeadline (line 146) | func (r *Stream) setReadDeadline() {
method Peek (line 162) | func (r *Stream) Peek(n int) ([]byte, error) {
method ReadN (line 186) | func (r *Stream) ReadN(n int) (p []byte, err error) {
method LastRead (line 211) | func (r *Stream) LastRead() time.Time {
method Write (line 219) | func (r *Stream) Write(p []byte) (n int, err error) {
method setWriteDeadline (line 234) | func (r *Stream) setWriteDeadline() {
method LastWrite (line 250) | func (r *Stream) LastWrite() time.Time {
method Close (line 258) | func (r *Stream) Close() error {
type deadline (line 60) | type deadline interface
function NewStream (line 66) | func NewStream(channel io.ReadWriteCloser, bufSize int) *Stream {
type dummyAddr (line 75) | type dummyAddr struct
method Network (line 77) | func (r dummyAddr) Network() string {
method String (line 81) | func (r dummyAddr) String() string {
FILE: openflow/transceiver/transceiver.go
constant maxIdleTime (line 45) | maxIdleTime = 10 * time.Second
constant readTimeout (line 47) | readTimeout = 1 * time.Second
constant writeTimeout (line 48) | writeTimeout = readTimeout * 2
type Writer (line 51) | type Writer interface
type WriteCloser (line 55) | type WriteCloser interface
type Transceiver (line 60) | type Transceiver struct
method Version (line 96) | func (r *Transceiver) Version() (negotiated bool, version uint8) {
method sendEchoRequest (line 117) | func (r *Transceiver) sendEchoRequest() error {
method Run (line 141) | func (r *Transceiver) Run(ctx context.Context) error {
method negotiate (line 186) | func (r *Transceiver) negotiate(ctx context.Context, reader <-chan []b...
method runReader (line 217) | func (r *Transceiver) runReader(ctx context.Context) <-chan []byte {
method readPacket (line 284) | func (r *Transceiver) readPacket() ([]byte, error) {
method Write (line 302) | func (r *Transceiver) Write(msg encoding.BinaryMarshaler) error {
method handleEcho (line 315) | func (r *Transceiver) handleEcho(packet []byte) (ok bool, err error) {
method handleOF10Echo (line 326) | func (r *Transceiver) handleOF10Echo(packet []byte) (ok bool, err erro...
method handleOF13Echo (line 338) | func (r *Transceiver) handleOF13Echo(packet []byte) (handled bool, err...
method dispatch (line 350) | func (r *Transceiver) dispatch(packet []byte) error {
method handleOF10Message (line 365) | func (r *Transceiver) handleOF10Message(packet []byte) error {
method handleOF13Message (line 397) | func (r *Transceiver) handleOF13Message(packet []byte) error {
method handleEchoRequest (line 431) | func (r *Transceiver) handleEchoRequest(packet []byte) error {
method handleEchoReply (line 458) | func (r *Transceiver) handleEchoReply(packet []byte) error {
method handleHello (line 488) | func (r *Transceiver) handleHello(packet []byte) error {
method handleError (line 500) | func (r *Transceiver) handleError(packet []byte) error {
method handleFeaturesReply (line 512) | func (r *Transceiver) handleFeaturesReply(packet []byte) error {
method handleGetConfigReply (line 524) | func (r *Transceiver) handleGetConfigReply(packet []byte) error {
method handleDescReply (line 536) | func (r *Transceiver) handleDescReply(packet []byte) error {
method handlePortDescReply (line 548) | func (r *Transceiver) handlePortDescReply(packet []byte) error {
method handlePortStatus (line 560) | func (r *Transceiver) handlePortStatus(packet []byte) error {
method handleFlowRemoved (line 572) | func (r *Transceiver) handleFlowRemoved(packet []byte) error {
method handlePacketIn (line 584) | func (r *Transceiver) handlePacketIn(packet []byte) error {
method handleBarrierReply (line 596) | func (r *Transceiver) handleBarrierReply(packet []byte) error {
method Close (line 608) | func (r *Transceiver) Close() error {
type Handler (line 69) | type Handler interface
function NewTransceiver (line 82) | func NewTransceiver(stream *Stream, handler Handler) *Transceiver {
function isTimeout (line 105) | func isTimeout(err error) bool {
function isTemporaryErr (line 277) | func isTemporaryErr(err error) bool {
FILE: protocol/arp.go
type ARP (line 31) | type ARP struct
method String (line 71) | func (r ARP) String() string {
method MarshalBinary (line 75) | func (r ARP) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 102) | func (r *ARP) UnmarshalBinary(data []byte) error {
function NewARPRequest (line 43) | func NewARPRequest(sha, tha net.HardwareAddr, spa, tpa net.IP) *ARP {
function NewARPReply (line 57) | func NewARPReply(sha, tha net.HardwareAddr, spa, tpa net.IP) *ARP {
FILE: protocol/checksum.go
function aroundCarry (line 28) | func aroundCarry(sum uint32) uint32 {
function calculateChecksum (line 42) | func calculateChecksum(header []byte) uint16 {
FILE: protocol/dhcp.go
type DHCP (line 36) | type DHCP struct
method MarshalBinary (line 61) | func (r *DHCP) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 115) | func (r *DHCP) UnmarshalBinary(data []byte) (err error) {
method Option (line 179) | func (r *DHCP) Option(code uint8) (opt DHCPOption, ok bool) {
type DHCPOpcode (line 54) | type DHCPOpcode
constant DHCPOpcodeRequest (line 57) | DHCPOpcodeRequest DHCPOpcode = 1
constant DHCPOpcodeReply (line 58) | DHCPOpcodeReply DHCPOpcode = 2
function unmarshalCString (line 188) | func unmarshalCString(data []byte) string {
function marshalIP (line 202) | func marshalIP(v []byte, addr net.IP) error {
function marshalMAC (line 220) | func marshalMAC(v []byte, mac net.HardwareAddr) error {
function unmarshalMAC (line 237) | func unmarshalMAC(data []byte) (net.HardwareAddr, error) {
type DHCPOption (line 249) | type DHCPOption struct
method MarshalBinary (line 254) | func (r *DHCPOption) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 268) | func (r *DHCPOption) UnmarshalBinary(data []byte) error {
FILE: protocol/dhcp_test.go
function TestCodec (line 36) | func TestCodec(t *testing.T) {
FILE: protocol/ethernet.go
type Ethernet (line 30) | type Ethernet struct
method MarshalBinary (line 36) | func (r Ethernet) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 55) | func (r *Ethernet) UnmarshalBinary(data []byte) error {
FILE: protocol/icmp.go
type ICMP (line 29) | type ICMP struct
type ICMPEcho (line 35) | type ICMPEcho struct
method MarshalBinary (line 61) | func (r ICMPEcho) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 78) | func (r *ICMPEcho) UnmarshalBinary(data []byte) error {
function NewICMPEchoRequest (line 42) | func NewICMPEchoRequest(id, seq uint16, payload []byte) *ICMPEcho {
function NewICMPEchoReply (line 53) | func NewICMPEchoReply(id, seq uint16, payload []byte) *ICMPEcho {
FILE: protocol/ipv4.go
type IPv4 (line 32) | type IPv4 struct
method MarshalBinary (line 80) | func (r IPv4) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 114) | func (r *IPv4) UnmarshalBinary(data []byte) error {
function NewIPv4 (line 49) | func NewIPv4(src, dst net.IP, protocol uint8, payload []byte) *IPv4 {
FILE: protocol/lldp.go
type LLDPChassisID (line 29) | type LLDPChassisID struct
type LLDPPortID (line 34) | type LLDPPortID struct
type LLDP (line 39) | type LLDP struct
method marshalChassisID (line 45) | func (r *LLDP) marshalChassisID() ([]byte, error) {
method marshalPortID (line 65) | func (r *LLDP) marshalPortID() ([]byte, error) {
method marshalTTL (line 85) | func (r *LLDP) marshalTTL() ([]byte, error) {
method MarshalBinary (line 97) | func (r *LLDP) MarshalBinary() ([]byte, error) {
method unmarshalChassisID (line 124) | func (r *LLDP) unmarshalChassisID(data []byte) (n int, err error) {
method unmarshalPortID (line 147) | func (r *LLDP) unmarshalPortID(data []byte) (n int, err error) {
method unmarshalTTL (line 170) | func (r *LLDP) unmarshalTTL(data []byte) (n int, err error) {
method UnmarshalBinary (line 190) | func (r *LLDP) UnmarshalBinary(data []byte) error {
FILE: protocol/tcp.go
type TCP (line 31) | type TCP struct
method SetPseudoHeader (line 47) | func (r *TCP) SetPseudoHeader(src, dst net.IP) {
method MarshalBinary (line 52) | func (r TCP) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 98) | func (r *TCP) UnmarshalBinary(data []byte) error {
FILE: protocol/udp.go
type UDP (line 31) | type UDP struct
method SetPseudoHeader (line 42) | func (r *UDP) SetPseudoHeader(src, dst net.IP) {
method MarshalBinary (line 47) | func (r UDP) MarshalBinary() ([]byte, error) {
method UnmarshalBinary (line 88) | func (r *UDP) UnmarshalBinary(data []byte) error {
FILE: vendor/github.com/ant0ine/go-json-rest/rest/access_log_apache.go
type AccessLogFormat (line 41) | type AccessLogFormat
constant CommonLogFormat (line 45) | CommonLogFormat = "%h %l %u %t \"%r\" %s %b"
constant CombinedLogFormat (line 48) | CombinedLogFormat = "%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-A...
constant DefaultLogFormat (line 51) | DefaultLogFormat = "%t %S\033[0m \033[36;1m%Dμs\033[0m \"%r\" \033[1;30m...
type AccessLogApacheMiddleware (line 57) | type AccessLogApacheMiddleware struct
method MiddlewareFunc (line 71) | func (mw *AccessLogApacheMiddleware) MiddlewareFunc(h HandlerFunc) Han...
method convertFormat (line 117) | func (mw *AccessLogApacheMiddleware) convertFormat() {
method executeTextTemplate (line 158) | func (mw *AccessLogApacheMiddleware) executeTextTemplate(util *accessL...
type accessLogUtil (line 169) | type accessLogUtil struct
method RemoteUser (line 175) | func (u *accessLogUtil) RemoteUser() string {
method ApacheQueryString (line 183) | func (u *accessLogUtil) ApacheQueryString() string {
method StartTime (line 191) | func (u *accessLogUtil) StartTime() *time.Time {
method ApacheRemoteAddr (line 199) | func (u *accessLogUtil) ApacheRemoteAddr() string {
method StatusCode (line 210) | func (u *accessLogUtil) StatusCode() int {
method ResponseTime (line 218) | func (u *accessLogUtil) ResponseTime() *time.Duration {
method Pid (line 226) | func (u *accessLogUtil) Pid() int {
method BytesWritten (line 231) | func (u *accessLogUtil) BytesWritten() int64 {
FILE: vendor/github.com/ant0ine/go-json-rest/rest/access_log_json.go
type AccessLogJsonMiddleware (line 13) | type AccessLogJsonMiddleware struct
method MiddlewareFunc (line 21) | func (mw *AccessLogJsonMiddleware) MiddlewareFunc(h HandlerFunc) Handl...
type AccessLogJsonRecord (line 39) | type AccessLogJsonRecord struct
method asJson (line 82) | func (r *AccessLogJsonRecord) asJson() []byte {
function makeAccessLogJsonRecord (line 49) | func makeAccessLogJsonRecord(r *Request) *AccessLogJsonRecord {
FILE: vendor/github.com/ant0ine/go-json-rest/rest/api.go
type Api (line 8) | type Api struct
method Use (line 23) | func (api *Api) Use(middlewares ...Middleware) {
method SetApp (line 28) | func (api *Api) SetApp(app App) {
method MakeHandler (line 35) | func (api *Api) MakeHandler() http.Handler {
function NewApi (line 14) | func NewApi() *Api {
FILE: vendor/github.com/ant0ine/go-json-rest/rest/auth_basic.go
type AuthBasicMiddleware (line 14) | type AuthBasicMiddleware struct
method MiddlewareFunc (line 30) | func (mw *AuthBasicMiddleware) MiddlewareFunc(handler HandlerFunc) Han...
method unauthorized (line 77) | func (mw *AuthBasicMiddleware) unauthorized(writer ResponseWriter) {
method decodeBasicAuthHeader (line 82) | func (mw *AuthBasicMiddleware) decodeBasicAuthHeader(header string) (u...
FILE: vendor/github.com/ant0ine/go-json-rest/rest/content_type_checker.go
type ContentTypeCheckerMiddleware (line 13) | type ContentTypeCheckerMiddleware struct
method MiddlewareFunc (line 16) | func (mw *ContentTypeCheckerMiddleware) MiddlewareFunc(handler Handler...
FILE: vendor/github.com/ant0ine/go-json-rest/rest/cors.go
type CorsMiddleware (line 16) | type CorsMiddleware struct
method MiddlewareFunc (line 53) | func (mw *CorsMiddleware) MiddlewareFunc(handler HandlerFunc) HandlerF...
FILE: vendor/github.com/ant0ine/go-json-rest/rest/gzip.go
type GzipMiddleware (line 15) | type GzipMiddleware struct
method MiddlewareFunc (line 18) | func (mw *GzipMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc {
type gzipResponseWriter (line 43) | type gzipResponseWriter struct
method WriteHeader (line 51) | func (w *gzipResponseWriter) WriteHeader(code int) {
method WriteJson (line 66) | func (w *gzipResponseWriter) WriteJson(v interface{}) error {
method Flush (line 80) | func (w *gzipResponseWriter) Flush() {
method CloseNotify (line 90) | func (w *gzipResponseWriter) CloseNotify() <-chan bool {
method Hijack (line 96) | func (w *gzipResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, er...
method Write (line 103) | func (w *gzipResponseWriter) Write(b []byte) (int, error) {
FILE: vendor/github.com/ant0ine/go-json-rest/rest/if.go
type IfMiddleware (line 9) | type IfMiddleware struct
method MiddlewareFunc (line 24) | func (mw *IfMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc {
FILE: vendor/github.com/ant0ine/go-json-rest/rest/json_indent.go
type JsonIndentMiddleware (line 15) | type JsonIndentMiddleware struct
method MiddlewareFunc (line 25) | func (mw *JsonIndentMiddleware) MiddlewareFunc(handler HandlerFunc) Ha...
type jsonIndentResponseWriter (line 46) | type jsonIndentResponseWriter struct
method EncodeJson (line 54) | func (w *jsonIndentResponseWriter) EncodeJson(v interface{}) ([]byte, ...
method WriteJson (line 64) | func (w *jsonIndentResponseWriter) WriteJson(v interface{}) error {
method WriteHeader (line 77) | func (w *jsonIndentResponseWriter) WriteHeader(code int) {
method Flush (line 84) | func (w *jsonIndentResponseWriter) Flush() {
method CloseNotify (line 94) | func (w *jsonIndentResponseWriter) CloseNotify() <-chan bool {
method Hijack (line 100) | func (w *jsonIndentResponseWriter) Hijack() (net.Conn, *bufio.ReadWrit...
method Write (line 107) | func (w *jsonIndentResponseWriter) Write(b []byte) (int, error) {
FILE: vendor/github.com/ant0ine/go-json-rest/rest/jsonp.go
type JsonpMiddleware (line 11) | type JsonpMiddleware struct
method MiddlewareFunc (line 20) | func (mw *JsonpMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc {
type jsonpResponseWriter (line 52) | type jsonpResponseWriter struct
method WriteHeader (line 59) | func (w *jsonpResponseWriter) WriteHeader(code int) {
method WriteJson (line 68) | func (w *jsonpResponseWriter) WriteJson(v interface{}) error {
method Flush (line 84) | func (w *jsonpResponseWriter) Flush() {
method CloseNotify (line 94) | func (w *jsonpResponseWriter) CloseNotify() <-chan bool {
method Hijack (line 100) | func (w *jsonpResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, e...
method Write (line 107) | func (w *jsonpResponseWriter) Write(b []byte) (int, error) {
FILE: vendor/github.com/ant0ine/go-json-rest/rest/middleware.go
type HandlerFunc (line 8) | type HandlerFunc
type App (line 12) | type App interface
type AppSimple (line 18) | type AppSimple
method AppFunc (line 21) | func (as AppSimple) AppFunc() HandlerFunc {
type Middleware (line 27) | type Middleware interface
type MiddlewareSimple (line 33) | type MiddlewareSimple
method MiddlewareFunc (line 36) | func (ms MiddlewareSimple) MiddlewareFunc(handler HandlerFunc) Handler...
function WrapMiddlewares (line 43) | func WrapMiddlewares(middlewares []Middleware, handler HandlerFunc) Hand...
function adapterFunc (line 53) | func adapterFunc(handler HandlerFunc) http.HandlerFunc {
FILE: vendor/github.com/ant0ine/go-json-rest/rest/powered_by.go
constant xPoweredByDefault (line 3) | xPoweredByDefault = "go-json-rest"
type PoweredByMiddleware (line 6) | type PoweredByMiddleware struct
method MiddlewareFunc (line 14) | func (mw *PoweredByMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFu...
FILE: vendor/github.com/ant0ine/go-json-rest/rest/recorder.go
type RecorderMiddleware (line 13) | type RecorderMiddleware struct
method MiddlewareFunc (line 16) | func (mw *RecorderMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc {
type recorderResponseWriter (line 37) | type recorderResponseWriter struct
method WriteHeader (line 45) | func (w *recorderResponseWriter) WriteHeader(code int) {
method WriteJson (line 52) | func (w *recorderResponseWriter) WriteJson(v interface{}) error {
method Flush (line 66) | func (w *recorderResponseWriter) Flush() {
method CloseNotify (line 76) | func (w *recorderResponseWriter) CloseNotify() <-chan bool {
method Hijack (line 82) | func (w *recorderResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter...
method Write (line 89) | func (w *recorderResponseWriter) Write(b []byte) (int, error) {
FILE: vendor/github.com/ant0ine/go-json-rest/rest/recover.go
type RecoverMiddleware (line 14) | type RecoverMiddleware struct
method MiddlewareFunc (line 29) | func (mw *RecoverMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc {
method logError (line 61) | func (mw *RecoverMiddleware) logError(message string) {
FILE: vendor/github.com/ant0ine/go-json-rest/rest/request.go
type Request (line 18) | type Request struct
method PathParam (line 29) | func (r *Request) PathParam(name string) string {
method DecodeJsonPayload (line 34) | func (r *Request) DecodeJsonPayload(v interface{}) error {
method BaseUrl (line 52) | func (r *Request) BaseUrl() *url.URL {
method UrlFor (line 71) | func (r *Request) UrlFor(path string, queryParams map[string][]string)...
method GetCorsInfo (line 101) | func (r *Request) GetCorsInfo() *CorsInfo {
type CorsInfo (line 87) | type CorsInfo struct
FILE: vendor/github.com/ant0ine/go-json-rest/rest/response.go
type ResponseWriter (line 13) | type ResponseWriter interface
function Error (line 40) | func Error(w ResponseWriter, error string, code int) {
function NotFound (line 51) | func NotFound(w ResponseWriter, r *Request) {
type responseWriter (line 62) | type responseWriter struct
method WriteHeader (line 67) | func (w *responseWriter) WriteHeader(code int) {
method EncodeJson (line 79) | func (w *responseWriter) EncodeJson(v interface{}) ([]byte, error) {
method WriteJson (line 88) | func (w *responseWriter) WriteJson(v interface{}) error {
method Write (line 101) | func (w *responseWriter) Write(b []byte) (int, error) {
method Flush (line 109) | func (w *responseWriter) Flush() {
method CloseNotify (line 118) | func (w *responseWriter) CloseNotify() <-chan bool {
method Hijack (line 124) | func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
FILE: vendor/github.com/ant0ine/go-json-rest/rest/route.go
type Route (line 9) | type Route struct
method MakePath (line 28) | func (route *Route) MakePath(pathParams map[string]string) string {
function Head (line 42) | func Head(pathExp string, handlerFunc HandlerFunc) *Route {
function Get (line 52) | func Get(pathExp string, handlerFunc HandlerFunc) *Route {
function Post (line 62) | func Post(pathExp string, handlerFunc HandlerFunc) *Route {
function Put (line 72) | func Put(pathExp string, handlerFunc HandlerFunc) *Route {
function Patch (line 82) | func Patch(pathExp string, handlerFunc HandlerFunc) *Route {
function Delete (line 91) | func Delete(pathExp string, handlerFunc HandlerFunc) *Route {
function Options (line 101) | func Options(pathExp string, handlerFunc HandlerFunc) *Route {
FILE: vendor/github.com/ant0ine/go-json-rest/rest/router.go
type router (line 11) | type router struct
method AppFunc (line 33) | func (rt *router) AppFunc() HandlerFunc {
method start (line 107) | func (rt *router) start() error {
method ofFirstDefinedRoute (line 142) | func (rt *router) ofFirstDefinedRoute(matches []*trie.Match) *trie.Mat...
method findRouteFromURL (line 159) | func (rt *router) findRouteFromURL(httpMethod string, urlObj *url.URL)...
method findRoute (line 184) | func (rt *router) findRoute(httpMethod, urlStr string) (*Route, map[st...
function MakeRouter (line 21) | func MakeRouter(routes ...*Route) (App, error) {
function escapedPath (line 61) | func escapedPath(urlObj *url.URL) string {
function escapedPathExp (line 73) | func escapedPathExp(pathExp string) (string, error) {
FILE: vendor/github.com/ant0ine/go-json-rest/rest/status.go
type StatusMiddleware (line 14) | type StatusMiddleware struct
method MiddlewareFunc (line 23) | func (mw *StatusMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc {
method GetStatus (line 91) | func (mw *StatusMiddleware) GetStatus() *Status {
type Status (line 75) | type Status struct
FILE: vendor/github.com/ant0ine/go-json-rest/rest/timer.go
type TimerMiddleware (line 10) | type TimerMiddleware struct
method MiddlewareFunc (line 13) | func (mw *TimerMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc {
FILE: vendor/github.com/ant0ine/go-json-rest/rest/trie/impl.go
function splitParam (line 17) | func splitParam(remaining string) (string, string) {
function splitRelaxed (line 25) | func splitRelaxed(remaining string) (string, string) {
type node (line 33) | type node struct
method addRoute (line 49) | func (n *node) addRoute(httpMethod, pathExp string, route interface{},...
method compress (line 165) | func (n *node) compress() {
method printDebug (line 217) | func (n *node) printDebug(level int) {
method find (line 292) | func (n *node) find(httpMethod, path string, context *findContext) {
function printFPadding (line 209) | func printFPadding(padding int, format string, a ...interface{}) {
type paramMatch (line 243) | type paramMatch struct
type findContext (line 248) | type findContext struct
method pushParams (line 259) | func (fc *findContext) pushParams(name, value string) {
method popParams (line 266) | func (fc *findContext) popParams() {
method paramsAsMap (line 270) | func (fc *findContext) paramsAsMap() map[string]string {
function newFindContext (line 253) | func newFindContext() *findContext {
type Match (line 285) | type Match struct
type Trie (line 337) | type Trie struct
method AddRoute (line 349) | func (t *Trie) AddRoute(httpMethod, pathExp string, route interface{})...
method Compress (line 354) | func (t *Trie) Compress() {
method printDebug (line 359) | func (t *Trie) printDebug() {
method FindRoutes (line 366) | func (t *Trie) FindRoutes(httpMethod, path string) []*Match {
method FindRoutesAndPathMatched (line 387) | func (t *Trie) FindRoutesAndPathMatched(httpMethod, path string) ([]*M...
method FindRoutesForPath (line 409) | func (t *Trie) FindRoutesForPath(path string) []*Match {
function New (line 342) | func New() *Trie {
FILE: vendor/github.com/boombuler/barcode/barcode.go
constant TypeAztec (line 6) | TypeAztec = "Aztec"
constant TypeCodabar (line 7) | TypeCodabar = "Codabar"
constant TypeCode128 (line 8) | TypeCode128 = "Code 128"
constant TypeCode39 (line 9) | TypeCode39 = "Code 39"
constant TypeCode93 (line 10) | TypeCode93 = "Code 93"
constant TypeDataMatrix (line 11) | TypeDataMatrix = "DataMatrix"
constant TypeEAN8 (line 12) | TypeEAN8 = "EAN 8"
constant TypeEAN13 (line 13) | TypeEAN13 = "EAN 13"
constant TypePDF (line 14) | TypePDF = "PDF417"
constant TypeQR (line 15) | TypeQR = "QR Code"
constant Type2of5 (line 16) | Type2of5 = "2 of 5"
constant Type2of5Interleaved (line 17) | Type2of5Interleaved = "2 of 5 (interleaved)"
type Metadata (line 21) | type Metadata struct
type Barcode (line 29) | type Barcode interface
type BarcodeIntCS (line 39) | type BarcodeIntCS interface
FILE: vendor/github.com/boombuler/barcode/qr/alphanumeric.go
constant charSet (line 11) | charSet string = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"
function stringToAlphaIdx (line 13) | func stringToAlphaIdx(content string) <-chan int {
function encodeAlphaNumeric (line 29) | func encodeAlphaNumeric(content string, ecl ErrorCorrectionLevel) (*util...
FILE: vendor/github.com/boombuler/barcode/qr/automatic.go
function encodeAuto (line 9) | func encodeAuto(content string, ecl ErrorCorrectionLevel) (*utils.BitLis...
FILE: vendor/github.com/boombuler/barcode/qr/blocks.go
type block (line 3) | type block struct
type blockList (line 7) | type blockList
method interleave (line 35) | func (bl blockList) interleave(vi *versionInfo) []byte {
function splitToBlocks (line 9) | func splitToBlocks(data <-chan byte, vi *versionInfo) blockList {
FILE: vendor/github.com/boombuler/barcode/qr/encoder.go
type encodeFn (line 11) | type encodeFn
type Encoding (line 14) | type Encoding
method getEncoder (line 29) | func (e Encoding) getEncoder() encodeFn {
method String (line 43) | func (e Encoding) String() string {
constant Auto (line 18) | Auto Encoding = iota
constant Numeric (line 20) | Numeric
constant AlphaNumeric (line 22) | AlphaNumeric
constant Unicode (line 24) | Unicode
constant unknownEncoding (line 26) | unknownEncoding
function Encode (line 58) | func Encode(content string, level ErrorCorrectionLevel, mode Encoding) (...
function render (line 71) | func render(data []byte, vi *versionInfo) *qrcode {
function setMasked (line 138) | func setMasked(x, y int, val bool, mask int, set func(int, int, bool)) {
function iterateModules (line 167) | func iterateModules(occupied *qrcode) <-chan image.Point {
function drawFinderPatterns (line 222) | func drawFinderPatterns(vi *versionInfo, set func(int, int, bool)) {
function drawAlignmentPatterns (line 240) | func drawAlignmentPatterns(occupied *qrcode, vi *versionInfo, set func(i...
function drawFormatInfo (line 304) | func drawFormatInfo(vi *versionInfo, usedMask int, set func(int, int, bo...
function drawVersionInfo (line 386) | func drawVersionInfo(vi *versionInfo, set func(int, int, bool)) {
function addPaddingAndTerminator (line 400) | func addPaddingAndTerminator(bl *utils.BitList, vi *versionInfo) {
FILE: vendor/github.com/boombuler/barcode/qr/errorcorrection.go
type errorCorrection (line 7) | type errorCorrection struct
method calcECC (line 18) | func (ec *errorCorrection) calcECC(data []byte, eccCount byte) []byte {
function newErrorCorrection (line 13) | func newErrorCorrection() *errorCorrection {
FILE: vendor/github.com/boombuler/barcode/qr/numeric.go
function encodeNumeric (line 11) | func encodeNumeric(content string, ecl ErrorCorrectionLevel) (*utils.Bit...
FILE: vendor/github.com/boombuler/barcode/qr/qrcode.go
type qrcode (line 12) | type qrcode struct
method Content (line 18) | func (qr *qrcode) Content() string {
method Metadata (line 22) | func (qr *qrcode) Metadata() barcode.Metadata {
method ColorModel (line 26) | func (qr *qrcode) ColorModel() color.Model {
method Bounds (line 30) | func (qr *qrcode) Bounds() image.Rectangle {
method At (line 34) | func (qr *qrcode) At(x, y int) color.Color {
method Get (line 41) | func (qr *qrcode) Get(x, y int) bool {
method Set (line 45) | func (qr *qrcode) Set(x, y int, val bool) {
method calcPenalty (line 49) | func (qr *qrcode) calcPenalty() uint {
method calcPenaltyRule1 (line 53) | func (qr *qrcode) calcPenaltyRule1() uint {
method calcPenaltyRule2 (line 94) | func (qr *qrcode) calcPenaltyRule2() uint {
method calcPenaltyRule3 (line 107) | func (qr *qrcode) calcPenaltyRule3() uint {
method calcPenaltyRule4 (line 147) | func (qr *qrcode) calcPenaltyRule4() uint {
function newBarcode (line 161) | func newBarcode(dim int) *qrcode {
FILE: vendor/github.com/boombuler/barcode/qr/unicode.go
function encodeUnicode (line 9) | func encodeUnicode(content string, ecl ErrorCorrectionLevel) (*utils.Bit...
FILE: vendor/github.com/boombuler/barcode/qr/versioninfo.go
type ErrorCorrectionLevel (line 6) | type ErrorCorrectionLevel
method String (line 19) | func (ecl ErrorCorrectionLevel) String() string {
constant L (line 10) | L ErrorCorrectionLevel = iota
constant M (line 12) | M
constant Q (line 14) | Q
constant H (line 16) | H
type encodingMode (line 33) | type encodingMode
constant numericMode (line 36) | numericMode encodingMode = 1
constant alphaNumericMode (line 37) | alphaNumericMode encodingMode = 2
constant byteMode (line 38) | byteMode encodingMode = 4
constant kanjiMode (line 39) | kanjiMode encodingMode = 8
type versionInfo (line 42) | type versionInfo struct
method totalDataBytes (line 215) | func (vi *versionInfo) totalDataBytes() int {
method charCountBits (line 221) | func (vi *versionInfo) charCountBits(m encodingMode) byte {
method modulWidth (line 257) | func (vi *versionInfo) modulWidth() int {
method alignmentPatternPlacements (line 261) | func (vi *versionInfo) alignmentPatternPlacements() []int {
function findSmallestVersionInfo (line 300) | func findSmallestVersionInfo(ecl ErrorCorrectionLevel, mode encodingMode...
FILE: vendor/github.com/boombuler/barcode/scaledbarcode.go
type wrapFunc (line 11) | type wrapFunc
type scaledBarcode (line 13) | type scaledBarcode struct
method Content (line 23) | func (bc *scaledBarcode) Content() string {
method Metadata (line 27) | func (bc *scaledBarcode) Metadata() Metadata {
method ColorModel (line 31) | func (bc *scaledBarcode) ColorModel() color.Model {
method Bounds (line 35) | func (bc *scaledBarcode) Bounds() image.Rectangle {
method At (line 39) | func (bc *scaledBarcode) At(x, y int) color.Color {
type intCSscaledBC (line 19) | type intCSscaledBC struct
method CheckSum (line 43) | func (bc *intCSscaledBC) CheckSum() int {
function Scale (line 51) | func Scale(bc Barcode, width, height int) (Barcode, error) {
function newScaledBC (line 62) | func newScaledBC(wrapped Barcode, wrapperFunc wrapFunc, rect image.Recta...
function scale2DCode (line 75) | func scale2DCode(bc Barcode, width, height int) (Barcode, error) {
function scale1DCode (line 107) | func scale1DCode(bc Barcode, width, height int) (Barcode, error) {
FILE: vendor/github.com/boombuler/barcode/utils/base1dcode.go
type base1DCode (line 11) | type base1DCode struct
method Content (line 22) | func (c *base1DCode) Content() string {
method Metadata (line 26) | func (c *base1DCode) Metadata() barcode.Metadata {
method ColorModel (line 30) | func (c *base1DCode) ColorModel() color.Model {
method Bounds (line 34) | func (c *base1DCode) Bounds() image.Rectangle {
method At (line 38) | func (c *base1DCode) At(x, y int) color.Color {
type base1DCodeIntCS (line 17) | type base1DCodeIntCS struct
method CheckSum (line 45) | func (c *base1DCodeIntCS) CheckSum() int {
function New1DCodeIntCheckSum (line 50) | func New1DCodeIntCheckSum(codeKind, content string, bars *BitList, check...
function New1DCode (line 55) | func New1DCode(codeKind, content string, bars *BitList) barcode.Barcode {
FILE: vendor/github.com/boombuler/barcode/utils/bitlist.go
type BitList (line 4) | type BitList struct
method Len (line 23) | func (bl *BitList) Len() int {
method grow (line 27) | func (bl *BitList) grow() {
method AddBit (line 41) | func (bl *BitList) AddBit(bits ...bool) {
method SetBit (line 53) | func (bl *BitList) SetBit(index int, value bool) {
method GetBit (line 64) | func (bl *BitList) GetBit(index int) bool {
method AddByte (line 71) | func (bl *BitList) AddByte(b byte) {
method AddBits (line 78) | func (bl *BitList) AddBits(b int, count byte) {
method GetBytes (line 85) | func (bl *BitList) GetBytes() []byte {
method IterateBytes (line 99) | func (bl *BitList) IterateBytes() <-chan byte {
function NewBitList (line 11) | func NewBitList(capacity int) *BitList {
FILE: vendor/github.com/boombuler/barcode/utils/galoisfield.go
type GaloisField (line 4) | type GaloisField struct
method Zero (line 36) | func (gf *GaloisField) Zero() *GFPoly {
method AddOrSub (line 41) | func (gf *GaloisField) AddOrSub(a, b int) int {
method Multiply (line 46) | func (gf *GaloisField) Multiply(a, b int) int {
method Divide (line 54) | func (gf *GaloisField) Divide(a, b int) int {
method Invers (line 63) | func (gf *GaloisField) Invers(num int) int {
function NewGaloisField (line 12) | func NewGaloisField(pp, fieldSize, b int) *GaloisField {
FILE: vendor/github.com/boombuler/barcode/utils/gfpoly.go
type GFPoly (line 3) | type GFPoly struct
method Degree (line 8) | func (gp *GFPoly) Degree() int {
method Zero (line 12) | func (gp *GFPoly) Zero() bool {
method GetCoefficient (line 17) | func (gp *GFPoly) GetCoefficient(degree int) int {
method AddOrSubstract (line 21) | func (gp *GFPoly) AddOrSubstract(other *GFPoly) *GFPoly {
method MultByMonominal (line 41) | func (gp *GFPoly) MultByMonominal(degree int, coeff int) *GFPoly {
method Multiply (line 53) | func (gp *GFPoly) Multiply(other *GFPoly) *GFPoly {
method Divide (line 72) | func (gp *GFPoly) Divide(other *GFPoly) (quotient *GFPoly, remainder *...
function NewMonominalPoly (line 89) | func NewMonominalPoly(field *GaloisField, degree int, coeff int) *GFPoly {
function NewGFPoly (line 98) | func NewGFPoly(field *GaloisField, coefficients []int) *GFPoly {
FILE: vendor/github.com/boombuler/barcode/utils/reedsolomon.go
type ReedSolomonEncoder (line 7) | type ReedSolomonEncoder struct
method getPolynomial (line 19) | func (rs *ReedSolomonEncoder) getPolynomial(degree int) *GFPoly {
method Encode (line 34) | func (rs *ReedSolomonEncoder) Encode(data []int, eccCount int) []int {
function NewReedSolomonEncoder (line 13) | func NewReedSolomonEncoder(gf *GaloisField) *ReedSolomonEncoder {
FILE: vendor/github.com/boombuler/barcode/utils/runeint.go
function RuneToInt (line 5) | func RuneToInt(r rune) int {
function IntToRune (line 14) | func IntToRune(i int) rune {
FILE: vendor/github.com/davecgh/go-spew/spew/bypass.go
constant UnsafeDisabled (line 33) | UnsafeDisabled = false
constant ptrSize (line 36) | ptrSize = unsafe.Sizeof((*byte)(nil))
type flag (line 39) | type flag
constant flagKindMask (line 54) | flagKindMask = flag(0x1f)
function flagField (line 80) | func flagField(v *reflect.Value) *flag {
function unsafeReflectValue (line 93) | func unsafeReflectValue(v reflect.Value) reflect.Value {
function init (line 105) | func init() {
FILE: vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
constant UnsafeDisabled (line 28) | UnsafeDisabled = true
function unsafeReflectValue (line 36) | func unsafeReflectValue(v reflect.Value) reflect.Value {
FILE: vendor/github.com/davecgh/go-spew/spew/common.go
function catchPanic (line 72) | func catchPanic(w io.Writer, v reflect.Value) {
function handleMethods (line 85) | func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handl...
function printBool (line 144) | func printBool(w io.Writer, val bool) {
function printInt (line 153) | func printInt(w io.Writer, val int64, base int) {
function printUint (line 158) | func printUint(w io.Writer, val uint64, base int) {
function printFloat (line 164) | func printFloat(w io.Writer, val float64, precision int) {
function printComplex (line 170) | func printComplex(w io.Writer, c complex128, floatPrecision int) {
function printHexPtr (line 185) | func printHexPtr(w io.Writer, p uintptr) {
type valuesSorter (line 219) | type valuesSorter struct
method Len (line 279) | func (s *valuesSorter) Len() int {
method Swap (line 285) | func (s *valuesSorter) Swap(i, j int) {
method Less (line 326) | func (s *valuesSorter) Less(i, j int) bool {
function newValuesSorter (line 228) | func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Inter...
function canSortSimply (line 256) | func canSortSimply(kind reflect.Kind) bool {
function valueSortLess (line 295) | func valueSortLess(a, b reflect.Value) bool {
function sortValues (line 336) | func sortValues(values []reflect.Value, cs *ConfigState) {
FILE: vendor/github.com/davecgh/go-spew/spew/config.go
type ConfigState (line 37) | type ConfigState struct
method Errorf (line 115) | func (c *ConfigState) Errorf(format string, a ...interface{}) (err err...
method Fprint (line 127) | func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, er...
method Fprintf (line 139) | func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interfa...
method Fprintln (line 150) | func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, ...
method Print (line 162) | func (c *ConfigState) Print(a ...interface{}) (n int, err error) {
method Printf (line 174) | func (c *ConfigState) Printf(format string, a ...interface{}) (n int, ...
method Println (line 186) | func (c *ConfigState) Println(a ...interface{}) (n int, err error) {
method Sprint (line 197) | func (c *ConfigState) Sprint(a ...interface{}) string {
method Sprintf (line 208) | func (c *ConfigState) Sprintf(format string, a ...interface{}) string {
method Sprintln (line 219) | func (c *ConfigState) Sprintln(a ...interface{}) string {
method NewFormatter (line 240) | func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter {
method Fdump (line 246) | func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) {
method Dump (line 273) | func (c *ConfigState) Dump(a ...interface{}) {
method Sdump (line 279) | func (c *ConfigState) Sdump(a ...interface{}) string {
method convertArgs (line 288) | func (c *ConfigState) convertArgs(args []interface{}) (formatters []in...
function NewDefaultConfig (line 304) | func NewDefaultConfig() *ConfigState {
FILE: vendor/github.com/davecgh/go-spew/spew/dump.go
type dumpState (line 51) | type dumpState struct
method indent (line 62) | func (d *dumpState) indent() {
method unpackValue (line 73) | func (d *dumpState) unpackValue(v reflect.Value) reflect.Value {
method dumpPtr (line 81) | func (d *dumpState) dumpPtr(v reflect.Value) {
method dumpSlice (line 161) | func (d *dumpState) dumpSlice(v reflect.Value) {
method dump (line 251) | func (d *dumpState) dump(v reflect.Value) {
function fdump (line 453) | func fdump(cs *ConfigState, w io.Writer, a ...interface{}) {
function Fdump (line 472) | func Fdump(w io.Writer, a ...interface{}) {
function Sdump (line 478) | func Sdump(a ...interface{}) string {
function Dump (line 507) | func Dump(a ...interface{}) {
FILE: vendor/github.com/davecgh/go-spew/spew/format.go
constant supportedFlags (line 28) | supportedFlags = "0-+# "
type formatState (line 34) | type formatState struct
method buildDefaultFormat (line 47) | func (f *formatState) buildDefaultFormat() (format string) {
method constructOrigFormat (line 65) | func (f *formatState) constructOrigFormat(verb rune) (format string) {
method unpackValue (line 94) | func (f *formatState) unpackValue(v reflect.Value) reflect.Value {
method formatPtr (line 105) | func (f *formatState) formatPtr(v reflect.Value) {
method format (line 201) | func (f *formatState) format(v reflect.Value) {
method Format (line 371) | func (f *formatState) Format(fs fmt.State, verb rune) {
function newFormatter (line 394) | func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter {
function NewFormatter (line 417) | func NewFormatter(v interface{}) fmt.Formatter {
FILE: vendor/github.com/davecgh/go-spew/spew/spew.go
function Errorf (line 32) | func Errorf(format string, a ...interface{}) (err error) {
function Fprint (line 44) | func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
function Fprintf (line 56) | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err e...
function Fprintln (line 67) | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
function Print (line 79) | func Print(a ...interface{}) (n int, err error) {
function Printf (line 91) | func Printf(format string, a ...interface{}) (n int, err error) {
function Println (line 103) | func Println(a ...interface{}) (n int, err error) {
function Sprint (line 114) | func Sprint(a ...interface{}) string {
function Sprintf (line 125) | func Sprintf(format string, a ...interface{}) string {
function Sprintln (line 136) | func Sprintln(a ...interface{}) string {
function convertArgs (line 142) | func convertArgs(args []interface{}) (formatters []interface{}) {
FILE: vendor/github.com/fsnotify/fsnotify/fen.go
type Watcher (line 14) | type Watcher struct
method Close (line 25) | func (w *Watcher) Close() error {
method Add (line 30) | func (w *Watcher) Add(name string) error {
method Remove (line 35) | func (w *Watcher) Remove(name string) error {
function NewWatcher (line 20) | func NewWatcher() (*Watcher, error) {
FILE: vendor/github.com/fsnotify/fsnotify/fsnotify.go
type Event (line 16) | type Event struct
method String (line 35) | func (e Event) String() string {
type Op (line 22) | type Op
constant Create (line 26) | Create Op = 1 << iota
constant Write (line 27) | Write
constant Remove (line 28) | Remove
constant Rename (line 29) | Rename
constant Chmod (line 30) | Chmod
FILE: vendor/github.com/fsnotify/fsnotify/inotify.go
type Watcher (line 23) | type Watcher struct
method isClosed (line 65) | func (w *Watcher) isClosed() bool {
method Close (line 75) | func (w *Watcher) Close() error {
method Add (line 93) | func (w *Watcher) Add(name string) error {
method Remove (line 126) | func (w *Watcher) Remove(name string) error {
method readEvents (line 172) | func (w *Watcher) readEvents() {
function NewWatcher (line 37) | func NewWatcher() (*Watcher, error) {
type watch (line 165) | type watch struct
method ignoreLinux (line 282) | func (e *Event) ignoreLinux(w *Watcher, wd int32, mask uint32) bool {
function newEvent (line 307) | func newEvent(name string, mask uint32) Event {
FILE: vendor/github.com/fsnotify/fsnotify/inotify_poller.go
type fdPoller (line 15) | type fdPoller struct
method wait (line 79) | func (poller *fdPoller) wait() (bool, error) {
method wake (line 149) | func (poller *fdPoller) wake() error {
method clearWake (line 162) | func (poller *fdPoller) clearWake() error {
method close (line 177) | func (poller *fdPoller) close() {
function emptyPoller (line 21) | func emptyPoller(fd int) *fdPoller {
function newFdPoller (line 32) | func newFdPoller(fd int) (*fdPoller, error) {
FILE: vendor/github.com/fsnotify/fsnotify/kqueue.go
type Watcher (line 22) | type Watcher struct
method Close (line 67) | func (w *Watcher) Close() error {
method Add (line 99) | func (w *Watcher) Add(name string) error {
method Remove (line 108) | func (w *Watcher) Remove(name string) error {
method addWatch (line 164) | func (w *Watcher) addWatch(name string, flags uint32) (string, error) {
method readEvents (line 266) | func (w *Watcher) readEvents() {
method watchDirectoryFiles (line 380) | func (w *Watcher) watchDirectoryFiles(dirPath string) error {
method sendDirectoryChangeEvents (line 406) | func (w *Watcher) sendDirectoryChangeEvents(dirPath string) {
method sendFileCreatedEventIfNew (line 425) | func (w *Watcher) sendFileCreatedEventIfNew(filePath string, fileInfo ...
method internalWatch (line 447) | func (w *Watcher) internalWatch(name string, fileInfo os.FileInfo) (st...
type pathInfo (line 38) | type pathInfo struct
function NewWatcher (line 44) | func NewWatcher() (*Watcher, error) {
constant noteAllEvents (line 156) | noteAllEvents = unix.NOTE_DELETE | unix.NOTE_WRITE | unix.NOTE_ATTRIB | ...
function newEvent (line 358) | func newEvent(name string, mask uint32) Event {
function newCreateEvent (line 375) | func newCreateEvent(name string) Event {
function kqueue (line 464) | func kqueue() (kq int, err error) {
function register (line 473) | func register(kq int, fds []int, flags int, fflags uint32) error {
function read (line 492) | func read(kq int, events []unix.Kevent_t, timeout *unix.Timespec) ([]uni...
function durationToTimespec (line 501) | func durationToTimespec(d time.Duration) unix.Timespec {
FILE: vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go
constant openMode (line 11) | openMode = unix.O_NONBLOCK | unix.O_RDONLY
FILE: vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go
constant openMode (line 12) | openMode = unix.O_EVTONLY
FILE: vendor/github.com/fsnotify/fsnotify/windows.go
type Watcher (line 21) | type Watcher struct
method Close (line 51) | func (w *Watcher) Close() error {
method Add (line 67) | func (w *Watcher) Add(name string) error {
method Remove (line 85) | func (w *Watcher) Remove(name string) error {
method wakeupReader (line 177) | func (w *Watcher) wakeupReader() error {
method addWatch (line 240) | func (w *Watcher) addWatch(pathname string, flags uint64) error {
method remWatch (line 289) | func (w *Watcher) remWatch(pathname string) error {
method deleteWatch (line 316) | func (w *Watcher) deleteWatch(watch *watch) {
method startRead (line 332) | func (w *Watcher) startRead(watch *watch) error {
method readEvents (line 373) | func (w *Watcher) readEvents() {
method sendEvent (line 517) | func (w *Watcher) sendEvent(name string, mask uint64) bool {
function NewWatcher (line 33) | func NewWatcher() (*Watcher, error) {
constant sysFSONESHOT (line 100) | sysFSONESHOT = 0x80000000
constant sysFSONLYDIR (line 101) | sysFSONLYDIR = 0x1000000
constant sysFSACCESS (line 104) | sysFSACCESS = 0x1
constant sysFSALLEVENTS (line 105) | sysFSALLEVENTS = 0xfff
constant sysFSATTRIB (line 106) | sysFSATTRIB = 0x4
constant sysFSCLOSE (line 107) | sysFSCLOSE = 0x18
constant sysFSCREATE (line 108) | sysFSCREATE = 0x100
constant sysFSDELETE (line 109) | sysFSDELETE = 0x200
constant sysFSDELETESELF (line 110) | sysFSDELETESELF = 0x400
constant sysFSMODIFY (line 111) | sysFSMODIFY = 0x2
constant sysFSMOVE (line 112) | sysFSMOVE = 0xc0
constant sysFSMOVEDFROM (line 113) | sysFSMOVEDFROM = 0x40
constant sysFSMOVEDTO (line 114) | sysFSMOVEDTO = 0x80
constant sysFSMOVESELF (line 115) | sysFSMOVESELF = 0x800
constant sysFSIGNORED (line 118) | sysFSIGNORED = 0x8000
constant sysFSQOVERFLOW (line 119) | sysFSQOVERFLOW = 0x4000
function newEvent (line 122) | func newEvent(name string, mask uint32) Event {
constant opAddWatch (line 143) | opAddWatch = iota
constant opRemoveWatch (line 144) | opRemoveWatch
constant provisional (line 148) | provisional uint64 = 1 << (32 + iota)
type input (line 151) | type input struct
type inode (line 158) | type inode struct
type watch (line 164) | type watch struct
type indexMap (line 174) | type indexMap
type watchMap (line 175) | type watchMap
method get (line 222) | func (m watchMap) get(ino *inode) *watch {
method set (line 230) | func (m watchMap) set(ino *inode, watch *watch) {
function getDir (line 185) | func getDir(pathname string) (dir string, err error) {
function getIno (line 199) | func getIno(path string) (ino *inode, err error) {
function toWindowsFlags (line 530) | func toWindowsFlags(mask uint64) uint32 {
function toFSnotifyFlags (line 547) | func toFSnotifyFlags(action uint32) uint64 {
FILE: vendor/github.com/go-sql-driver/mysql/appengine.go
function init (line 17) | func init() {
FILE: vendor/github.com/go-sql-driver/mysql/buffer.go
constant defaultBufSize (line 17) | defaultBufSize = 4096
type buffer (line 24) | type buffer struct
method fill (line 41) | func (b *buffer) fill(need int) error {
method readNext (line 94) | func (b *buffer) readNext(need int) ([]byte, error) {
method takeBuffer (line 112) | func (b *buffer) takeBuffer(length int) []byte {
method takeSmallBuffer (line 132) | func (b *buffer) takeSmallBuffer(length int) []byte {
method takeCompleteBuffer (line 142) | func (b *buffer) takeCompleteBuffer() []byte {
function newBuffer (line 32) | func newBuffer(nc net.Conn) buffer {
FILE: vendor/github.com/go-sql-driver/mysql/collations.go
constant defaultCollation (line 11) | defaultCollation = "utf8_general_ci"
constant binaryCollation (line 12) | binaryCollation = "binary"
FILE: vendor/github.com/go-sql-driver/mysql/connection.go
type mysqlContext (line 21) | type mysqlContext interface
type mysqlConn (line 30) | type mysqlConn struct
method handleParams (line 54) | func (mc *mysqlConn) handleParams() (err error) {
method markBadConn (line 83) | func (mc *mysqlConn) markBadConn(err error) error {
method Begin (line 93) | func (mc *mysqlConn) Begin() (driver.Tx, error) {
method begin (line 97) | func (mc *mysqlConn) begin(readOnly bool) (driver.Tx, error) {
method Close (line 115) | func (mc *mysqlConn) Close() (err error) {
method cleanup (line 130) | func (mc *mysqlConn) cleanup() {
method error (line 145) | func (mc *mysqlConn) error() error {
method Prepare (line 155) | func (mc *mysqlConn) Prepare(query string) (driver.Stmt, error) {
method interpolateParams (line 187) | func (mc *mysqlConn) interpolateParams(query string, args []driver.Val...
method Exec (line 309) | func (mc *mysqlConn) Exec(query string, args []driver.Value) (driver.R...
method exec (line 339) | func (mc *mysqlConn) exec(query string) error {
method Query (line 366) | func (mc *mysqlConn) Query(query string, args []driver.Value) (driver....
method query (line 370) | func (mc *mysqlConn) query(query string, args []driver.Value) (*textRo...
method getSystemVar (line 417) | func (mc *mysqlConn) getSystemVar(name string) ([]byte, error) {
method cancel (line 446) | func (mc *mysqlConn) cancel(err error) {
method finish (line 452) | func (mc *mysqlConn) finish() {
FILE: vendor/github.com/go-sql-driver/mysql/connection_go18.go
method Ping (line 20) | func (mc *mysqlConn) Ping(ctx context.Context) error {
method BeginTx (line 42) | func (mc *mysqlConn) BeginTx(ctx context.Context, opts driver.TxOptions)...
method QueryContext (line 62) | func (mc *mysqlConn) QueryContext(ctx context.Context, query string, arg...
method ExecContext (line 81) | func (mc *mysqlConn) ExecContext(ctx context.Context, query string, args...
method PrepareContext (line 95) | func (mc *mysqlConn) PrepareContext(ctx context.Context, query string) (...
method QueryContext (line 115) | func (stmt *mysqlStmt) QueryContext(ctx context.Context, args []driver.N...
method ExecContext (line 134) | func (stmt *mysqlStmt) ExecContext(ctx context.Context, args []driver.Na...
method watchCancel (line 148) | func (mc *mysqlConn) watchCancel(ctx context.Context) error {
method startWatcher (line 174) | func (mc *mysqlConn) startWatcher() {
method CheckNamedValue (line 199) | func (mc *mysqlConn) CheckNamedValue(nv *driver.NamedValue) (err error) {
FILE: vendor/github.com/go-sql-driver/mysql/const.go
constant defaultMaxAllowedPacket (line 12) | defaultMaxAllowedPacket = 4 << 20
constant minProtocolVersion (line 13) | minProtocolVersion = 10
constant maxPacketSize (line 14) | maxPacketSize = 1<<24 - 1
constant timeFormat (line 15) | timeFormat = "2006-01-02 15:04:05.999999"
constant iOK (line 22) | iOK byte = 0x00
constant iLocalInFile (line 23) | iLocalInFile byte = 0xfb
constant iEOF (line 24) | iEOF byte = 0xfe
constant iERR (line 25) | iERR byte = 0xff
type clientFlag (line 29) | type clientFlag
constant clientLongPassword (line 32) | clientLongPassword clientFlag = 1 << iota
constant clientFoundRows (line 33) | clientFoundRows
constant clientLongFlag (line 34) | clientLongFlag
constant clientConnectWithDB (line 35) | clientConnectWithDB
constant clientNoSchema (line 36) | clientNoSchema
constant clientCompress (line 37) | clientCompress
constant clientODBC (line 38) | clientODBC
constant clientLocalFiles (line 39) | clientLocalFiles
constant clientIgnoreSpace (line 40) | clientIgnoreSpace
constant clientProtocol41 (line 41) | clientProtocol41
constant clientInteractive (line 42) | clientInteractive
constant clientSSL (line 43) | clientSSL
constant clientIgnoreSIGPIPE (line 44) | clientIgnoreSIGPIPE
constant clientTransactions (line 45) | clientTransactions
constant clientReserved (line 46) | clientReserved
constant clientSecureConn (line 47) | clientSecureConn
constant clientMultiStatements (line 48) | clientMultiStatements
constant clientMultiResults (line 49) | clientMultiResults
constant clientPSMultiResults (line 50) | clientPSMultiResults
constant clientPluginAuth (line 51) | clientPluginAuth
constant clientConnectAttrs (line 52) | clientConnectAttrs
constant clientPluginAuthLenEncClientData (line 53) | clientPluginAuthLenEncClientData
constant clientCanHandleExpiredPasswords (line 54) | clientCanHandleExpiredPasswords
constant clientSessionTrack (line 55) | clientSessionTrack
constant clientDeprecateEOF (line 56) | clientDeprecateEOF
constant comQuit (line 60) | comQuit byte = iota + 1
constant comInitDB (line 61) | comInitDB
constant comQuery (line 62) | comQuery
constant comFieldList (line 63) | comFieldList
constant comCreateDB (line 64) | comCreateDB
constant comDropDB (line 65) | comDropDB
constant comRefresh (line 66) | comRefresh
constant comShutdown (line 67) | comShutdown
constant comStatistics (line 68) | comStatistics
constant comProcessInfo (line 69) | comProcessInfo
constant comConnect (line 70) | comConnect
constant comProcessKill (line 71) | comProcessKill
constant comDebug (line 72) | comDebug
constant comPing (line 73) | comPing
constant comTime (line 74) | comTime
constant comDelayedInsert (line 75) | comDelayedInsert
constant comChangeUser (line 76) | comChangeUser
constant comBinlogDump (line 77) | comBinlogDump
constant comTableDump (line 78) | comTableDump
constant comConnectOut (line 79) | comConnectOut
constant comRegisterSlave (line 80) | comRegisterSlave
constant comStmtPrepare (line 81) | comStmtPrepare
constant comStmtExecute (line 82) | comStmtExecute
constant comStmtSendLongData (line 83) | comStmtSendLongData
constant comStmtClose (line 84) | comStmtClose
constant comStmtReset (line 85) | comStmtReset
constant comSetOption (line 86) | comSetOption
constant comStmtFetch (line 87) | comStmtFetch
type fieldType (line 91) | type fieldType
constant fieldTypeDecimal (line 94) | fieldTypeDecimal fieldType = iota
constant fieldTypeTiny (line 95) | fieldTypeTiny
constant fieldTypeShort (line 96) | fieldTypeShort
constant fieldTypeLong (line 97) | fieldTypeLong
constant fieldTypeFloat (line 98) | fieldTypeFloat
constant fieldTypeDouble (line 99) | fieldTypeDouble
constant fieldTypeNULL (line 100) | fieldTypeNULL
constant fieldTypeTimestamp (line 101) | fieldTypeTimestamp
constant fieldTypeLongLong (line 102) | fieldTypeLongLong
constant fieldTypeInt24 (line 103) | fieldTypeInt24
constant fieldTypeDate (line 104) | fieldTypeDate
constant fieldTypeTime (line 105) | fieldTypeTime
constant fieldTypeDateTime (line 106) | fieldTypeDateTime
constant fieldTypeYear (line 107) | fieldTypeYear
constant fieldTypeNewDate (line 108) | fieldTypeNewDate
constant fieldTypeVarChar (line 109) | fieldTypeVarChar
constant fieldTypeBit (line 110) | fieldTypeBit
constant fieldTypeJSON (line 113) | fieldTypeJSON fieldType = iota + 0xf5
constant fieldTypeNewDecimal (line 114) | fieldTypeNewDecimal
constant fieldTypeEnum (line 115) | fieldTypeEnum
constant fieldTypeSet (line 116) | fieldTypeSet
constant fieldTypeTinyBLOB (line 117) | fieldTypeTinyBLOB
constant fieldTypeMediumBLOB (line 118) | fieldTypeMediumBLOB
constant fieldTypeLongBLOB (line 119) | fieldTypeLongBLOB
constant fieldTypeBLOB (line 120) | fieldTypeBLOB
constant fieldTypeVarString (line 121) | fieldTypeVarString
constant fieldTypeString (line 122) | fieldTypeString
constant fieldTypeGeometry (line 123) | fieldTypeGeometry
type fieldFlag (line 126) | type fieldFlag
constant flagNotNULL (line 129) | flagNotNULL fieldFlag = 1 << iota
constant flagPriKey (line 130) | flagPriKey
constant flagUniqueKey (line 131) | flagUniqueKey
constant flagMultipleKey (line 132) | flagMultipleKey
constant flagBLOB (line 133) | flagBLOB
constant flagUnsigned (line 134) | flagUnsigned
constant flagZeroFill (line 135) | flagZeroFill
constant flagBinary (line 136) | flagBinary
constant flagEnum (line 137) | flagEnum
constant flagAutoIncrement (line 138) | flagAutoIncrement
constant flagTimestamp (line 139) | flagTimestamp
constant flagSet (line 140) | flagSet
constant flagUnknown1 (line 141) | flagUnknown1
constant flagUnknown2 (line 142) | flagUnknown2
constant flagUnknown3 (line 143) | flagUnknown3
constant flagUnknown4 (line 144) | flagUnknown4
type statusFlag (line 148) | type statusFlag
constant statusInTrans (line 151) | statusInTrans statusFlag = 1 << iota
constant statusInAutocommit (line 152) | statusInAutocommit
constant statusReserved (line 153) | statusReserved
constant statusMoreResultsExists (line 154) | statusMoreResultsExists
constant statusNoGoodIndexUsed (line 155) | statusNoGoodIndexUsed
constant statusNoIndexUsed (line 156) | statusNoIndexUsed
constant statusCursorExists (line 157) | statusCursorExists
constant statusLastRowSent (line 158) | statusLastRowSent
constant statusDbDropped (line 159) | statusDbDropped
constant statusNoBackslashEscapes (line 160) | statusNoBackslashEscapes
constant statusMetadataChanged (line 161) | statusMetadataChanged
constant statusQueryWasSlow (line 162) | statusQueryWasSlow
constant statusPsOutParams (line 163) | statusPsOutParams
constant statusInTransReadonly (line 164) | statusInTransReadonly
constant statusSessionStateChanged (line 165) | statusSessionStateChanged
FILE: vendor/github.com/go-sql-driver/mysql/driver.go
type watcher (line 26) | type watcher interface
type MySQLDriver (line 32) | type MySQLDriver struct
method Open (line 53) | func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
type DialFunc (line 36) | type DialFunc
function RegisterDial (line 43) | func RegisterDial(net string, dial DialFunc) {
function handleAuthResult (line 147) | func handleAuthResult(mc *mysqlConn, oldCipher []byte) error {
function init (line 191) | func init() {
FILE: vendor/github.com/go-sql-driver/mysql/dsn.go
type Config (line 34) | type Config struct
method normalize (line 72) | func (cfg *Config) normalize() error {
method FormatDSN (line 111) | func (cfg *Config) FormatDSN() string {
function NewConfig (line 63) | func NewConfig() *Config {
function ParseDSN (line 323) | func ParseDSN(dsn string) (cfg *Config, err error) {
function parseDSNParams (line 401) | func parseDSNParams(cfg *Config, params string) (err error) {
function ensureHavePort (line 579) | func ensureHavePort(addr string) string {
FILE: vendor/github.com/go-sql-driver/mysql/errors.go
type Logger (line 43) | type Logger interface
function SetLogger (line 49) | func SetLogger(logger Logger) error {
type MySQLError (line 58) | type MySQLError struct
method Error (line 63) | func (me *MySQLError) Error() string {
FILE: vendor/github.com/go-sql-driver/mysql/fields.go
type mysqlField (line 118) | type mysqlField struct
method typeDatabaseName (line 16) | func (mf *mysqlField) typeDatabaseName() string {
method scanType (line 128) | func (mf *mysqlField) scanType() reflect.Type {
FILE: vendor/github.com/go-sql-driver/mysql/infile.go
function RegisterLocalFile (line 37) | func RegisterLocalFile(filePath string) {
function DeregisterLocalFile (line 49) | func DeregisterLocalFile(filePath string) {
function RegisterReaderHandler (line 70) | func RegisterReaderHandler(name string, handler func() io.Reader) {
function DeregisterReaderHandler (line 83) | func DeregisterReaderHandler(name string) {
function deferredClose (line 89) | func deferredClose(err *error, closer io.Closer) {
method handleInFileRequest (line 96) | func (mc *mysqlConn) handleInFileRequest(name string) (err error) {
FILE: vendor/github.com/go-sql-driver/mysql/packets.go
method readPacket (line 27) | func (mc *mysqlConn) readPacket() ([]byte, error) {
method writePacket (line 92) | func (mc *mysqlConn) writePacket(data []byte) error {
method readInitPacket (line 157) | func (mc *mysqlConn) readInitPacket() ([]byte, error) {
method writeAuthPacket (line 246) | func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
method writeOldAuthPacket (line 362) | func (mc *mysqlConn) writeOldAuthPacket(cipher []byte) error {
method writeClearAuthPacket (line 386) | func (mc *mysqlConn) writeClearAuthPacket() error {
method writeNativeAuthPacket (line 405) | func (mc *mysqlConn) writeNativeAuthPacket(cipher []byte) error {
method writeCommandPacket (line 429) | func (mc *mysqlConn) writeCommandPacket(command byte) error {
method writeCommandPacketStr (line 447) | func (mc *mysqlConn) writeCommandPacketStr(command byte, arg string) err...
method writeCommandPacketUint32 (line 469) | func (mc *mysqlConn) writeCommandPacketUint32(command byte, arg uint32) ...
method readResultOK (line 498) | func (mc *mysqlConn) readResultOK() ([]byte, error) {
method readResultSetHeaderPacket (line 540) | func (mc *mysqlConn) readResultSetHeaderPacket() (int, error) {
method handleErrorPacket (line 568) | func (mc *mysqlConn) handleErrorPacket(data []byte) error {
function readStatus (line 609) | func readStatus(b []byte) statusFlag {
method handleOkPacket (line 615) | func (mc *mysqlConn) handleOkPacket(data []byte) error {
method readColumns (line 639) | func (mc *mysqlConn) readColumns(count int) ([]mysqlField, error) {
method readRow (line 739) | func (rows *textRows) readRow(dest []driver.Value) error {
method readUntilEOF (line 807) | func (mc *mysqlConn) readUntilEOF() error {
method readPrepareResultPacket (line 832) | func (stmt *mysqlStmt) readPrepareResultPacket() (uint16, error) {
method writeCommandLongData (line 859) | func (stmt *mysqlStmt) writeCommandLongData(paramID int, arg []byte) err...
method writeExecutePacket (line 912) | func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
method discardResults (line 1127) | func (mc *mysqlConn) discardResults() error {
method readRow (line 1148) | func (rows *binaryRows) readRow(dest []driver.Value) error {
FILE: vendor/github.com/go-sql-driver/mysql/result.go
type mysqlResult (line 11) | type mysqlResult struct
method LastInsertId (line 16) | func (res *mysqlResult) LastInsertId() (int64, error) {
method RowsAffected (line 20) | func (res *mysqlResult) RowsAffected() (int64, error) {
FILE: vendor/github.com/go-sql-driver/mysql/rows.go
type resultSet (line 18) | type resultSet struct
type mysqlRows (line 24) | type mysqlRows struct
method Columns (line 38) | func (rows *mysqlRows) Columns() []string {
method ColumnTypeDatabaseTypeName (line 62) | func (rows *mysqlRows) ColumnTypeDatabaseTypeName(i int) string {
method ColumnTypeNullable (line 70) | func (rows *mysqlRows) ColumnTypeNullable(i int) (nullable, ok bool) {
method ColumnTypePrecisionScale (line 74) | func (rows *mysqlRows) ColumnTypePrecisionScale(i int) (int64, int64, ...
method ColumnTypeScanType (line 96) | func (rows *mysqlRows) ColumnTypeScanType(i int) reflect.Type {
method Close (line 100) | func (rows *mysqlRows) Close() (err error) {
method HasNextResultSet (line 128) | func (rows *mysqlRows) HasNextResultSet() (b bool) {
method nextResultSet (line 135) | func (rows *mysqlRows) nextResultSet() (int, error) {
method nextNotEmptyResultSet (line 159) | func (rows *mysqlRows) nextNotEmptyResultSet() (int, error) {
type binaryRows (line 30) | type binaryRows struct
method NextResultSet (line 174) | func (rows *binaryRows) NextResultSet() error {
method Next (line 184) | func (rows *binaryRows) Next(dest []driver.Value) error {
type textRows (line 34) | type textRows struct
method NextResultSet (line 196) | func (rows *textRows) NextResultSet() (err error) {
method Next (line 206) | func (rows *textRows) Next(dest []driver.Value) error {
FILE: vendor/github.com/go-sql-driver/mysql/statement.go
type mysqlStmt (line 19) | type mysqlStmt struct
method Close (line 25) | func (stmt *mysqlStmt) Close() error {
method NumInput (line 39) | func (stmt *mysqlStmt) NumInput() int {
method ColumnConverter (line 43) | func (stmt *mysqlStmt) ColumnConverter(idx int) driver.ValueConverter {
method Exec (line 47) | func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
method Query (line 91) | func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) {
method query (line 95) | func (stmt *mysqlStmt) query(args []driver.Value) (*binaryRows, error) {
type converter (line 133) | type converter struct
method ConvertValue (line 140) | func (c converter) ConvertValue(v interface{}) (driver.Value, error) {
function callValuerValue (line 204) | func callValuerValue(vr driver.Valuer) (v driver.Value, err error) {
FILE: vendor/github.com/go-sql-driver/mysql/transaction.go
type mysqlTx (line 11) | type mysqlTx struct
method Commit (line 15) | func (tx *mysqlTx) Commit() (err error) {
method Rollback (line 24) | fu
Condensed preview — 698 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (6,829K chars).
[
{
"path": ".gitlab-ci.yml",
"chars": 431,
"preview": "image: golang:1.12\n\nbefore_script:\n - mkdir -p /go/src/github.com/superkkt\n - cp -rp /builds/superkkt/cherry /go/src/g"
},
{
"path": "Changelog",
"chars": 19327,
"preview": "* v0.14.2 (2019-09-20)\n\n3faead4 Fix the unexpected master change (See #44)\n\n* v0.14.1 (2019-09-03)\n\nb321987 Remove passw"
},
{
"path": "Dockerfile",
"chars": 529,
"preview": "# Start from a Debian image with the latest version of Go installed\n# and a workspace (GOPATH) configured at /go.\nFROM g"
},
{
"path": "Godeps/Godeps.json",
"chars": 3889,
"preview": "{\n\t\"ImportPath\": \"github.com/superkkt/cherry\",\n\t\"GoVersion\": \"go1.10\",\n\t\"GodepVersion\": \"v79\",\n\t\"Packages\": [\n\t\t\"./...\"\n"
},
{
"path": "Godeps/Readme",
"chars": 136,
"preview": "This directory tree is generated automatically by godep.\n\nPlease do not edit.\n\nSee https://github.com/tools/godep for mo"
},
{
"path": "Gopkg.toml",
"chars": 1025,
"preview": "# Gopkg.toml example\n#\n# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html\n# for detailed Gopkg.toml documentat"
},
{
"path": "LICENSE",
"chars": 15225,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software F"
},
{
"path": "README.md",
"chars": 2910,
"preview": "# Cherry\n\nCherry is an OpenFlow controller written in Go that supports OpenFlow 1.0 and 1.3 protocols. This project is n"
},
{
"path": "api/core/api.go",
"chars": 4106,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "api/response.go",
"chars": 2938,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "api/server.go",
"chars": 2938,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "api/ui/api.go",
"chars": 8048,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "api/ui/category.go",
"chars": 9427,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "api/ui/component.go",
"chars": 9978,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "api/ui/group.go",
"chars": 9180,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "api/ui/host.go",
"chars": 19761,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "api/ui/ip.go",
"chars": 3035,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "api/ui/log.go",
"chars": 4688,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "api/ui/network.go",
"chars": 8374,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "api/ui/session.go",
"chars": 2315,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "api/ui/switch.go",
"chars": 8926,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "api/ui/user.go",
"chars": 14081,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "api/ui/vip.go",
"chars": 9463,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "cmd/cherry/cherry.yaml",
"chars": 954,
"preview": "default:\n port: 6633\n # The logger will only write log messages whose level is equal to or higher than log_level.\n"
},
{
"path": "cmd/cherry/main.go",
"chars": 8725,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "cmd/walnut/main.go",
"chars": 5743,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "cmd/walnut/sdk.go",
"chars": 2729,
"preview": "/*\n * Copyright 2019 Samjung Data Service, Inc. All Rights Reserved.\n *\n * Authors:\n * \tKitae Kim <superkkt@sds.co.kr>\n "
},
{
"path": "cmd/walnut/walnut.yaml",
"chars": 925,
"preview": "# NOTE:\n#\n# Parameters marked as a DYNAMIC can be dynamically updated without restarting the daemon.\n\nlog:\n # (DYNAMI"
},
{
"path": "database/mysql.go",
"chars": 69735,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "database/mysql_schema.sql",
"chars": 16373,
"preview": "-- MySQL dump 10.14 Distrib 5.5.44-MariaDB, for debian-linux-gnu (x86_64)\n--\n-- Host: localhost Database: cherry\n-- "
},
{
"path": "database/random.go",
"chars": 1219,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "election/election.go",
"chars": 2921,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "graph/graph.go",
"chars": 9454,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "graph/graph_test.go",
"chars": 13125,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved. \n * Kitae"
},
{
"path": "ldap/client.go",
"chars": 2741,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "ldap/conn.go",
"chars": 1628,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "log/syslog.go",
"chars": 1891,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "network/controller.go",
"chars": 3566,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "network/device.go",
"chars": 11813,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "network/error.go",
"chars": 1056,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "network/flow_cache.go",
"chars": 2347,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "network/link.go",
"chars": 1408,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "network/node.go",
"chars": 1251,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "network/of10_session.go",
"chars": 4561,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "network/of13_session.go",
"chars": 7646,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "network/port.go",
"chars": 1962,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "network/reserve.go",
"chars": 1707,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n * "
},
{
"path": "network/reserve_test.go",
"chars": 2941,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n * "
},
{
"path": "network/session.go",
"chars": 19434,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "network/topology.go",
"chars": 7162,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "northbound/app/announcer/announcer.go",
"chars": 2942,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n *\n "
},
{
"path": "northbound/app/announcer/backoff.go",
"chars": 2858,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "northbound/app/dhcp/dhcp.go",
"chars": 8176,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n * "
},
{
"path": "northbound/app/discovery/discovery.go",
"chars": 9870,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "northbound/app/l2switch/storm_controller.go",
"chars": 2357,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "northbound/app/l2switch/storm_controller_test.go",
"chars": 2968,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "northbound/app/l2switch/switch.go",
"chars": 10000,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "northbound/app/monitor/monitor.go",
"chars": 2827,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "northbound/app/monitor/sendmail.go",
"chars": 806,
"preview": "package monitor\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"net/smtp\"\n\t\"strings\"\n\n\t\"github.com/pkg/errors\"\n)\n\n// msg is a RFC 822-style em"
},
{
"path": "northbound/app/processor.go",
"chars": 3952,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "northbound/app/proxyarp/arp.go",
"chars": 4407,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "northbound/app/proxyarp/error.go",
"chars": 1060,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "northbound/app/virtualip/virtualip.go",
"chars": 3351,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "northbound/manager.go",
"chars": 4005,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/action.go",
"chars": 2893,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/barrier.go",
"chars": 1032,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/config.go",
"chars": 1400,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/const.go",
"chars": 923,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/description.go",
"chars": 1170,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/echo.go",
"chars": 1736,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/error.go",
"chars": 1670,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/factory.go",
"chars": 2857,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/features.go",
"chars": 1161,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/flow_mod.go",
"chars": 1506,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/flow_removed.go",
"chars": 1180,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/flow_stats.go",
"chars": 1209,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/hello.go",
"chars": 1209,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/instruction.go",
"chars": 1043,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/match.go",
"chars": 2480,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/message.go",
"chars": 2468,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/action.go",
"chars": 5308,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/barrier.go",
"chars": 1388,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/config.go",
"chars": 3291,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/const.go",
"chars": 6134,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/description.go",
"chars": 2491,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/echo.go",
"chars": 1247,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/factory.go",
"chars": 4716,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/features.go",
"chars": 2719,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/flow_mod.go",
"chars": 4060,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/flow_removed.go",
"chars": 2863,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/flow_stats.go",
"chars": 2617,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/hello.go",
"chars": 1067,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/instruction.go",
"chars": 1602,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/match.go",
"chars": 11336,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/packet_in.go",
"chars": 2091,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/packet_out.go",
"chars": 2552,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/port.go",
"chars": 2857,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/port_status.go",
"chars": 1737,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of10/queue.go",
"chars": 4572,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/action.go",
"chars": 4284,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/barrier.go",
"chars": 1388,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/config.go",
"chars": 3291,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/const.go",
"chars": 9321,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/echo.go",
"chars": 1247,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/factory.go",
"chars": 4651,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/features.go",
"chars": 2404,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/flow_mod.go",
"chars": 4044,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/flow_removed.go",
"chars": 2833,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/hello.go",
"chars": 1067,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/instruction.go",
"chars": 2810,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/match.go",
"chars": 16301,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/multipart_description.go",
"chars": 2457,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/multipart_flow_stats.go",
"chars": 2711,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/multipart_port_description.go",
"chars": 2090,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/multipart_table_features.go",
"chars": 1475,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/packet_in.go",
"chars": 2434,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/packet_out.go",
"chars": 2448,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/port.go",
"chars": 3159,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/port_status.go",
"chars": 1709,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/of13/queue.go",
"chars": 4989,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/packet_in.go",
"chars": 1077,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/packet_out.go",
"chars": 1094,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/port.go",
"chars": 2952,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/port_description.go",
"chars": 1050,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/port_status.go",
"chars": 1085,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/queue.go",
"chars": 1540,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/table_features.go",
"chars": 1008,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/transceiver/stream.go",
"chars": 6293,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "openflow/transceiver/transceiver.go",
"chars": 15036,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "protocol/arp.go",
"chars": 3412,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "protocol/checksum.go",
"chars": 1349,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved. \n * Kitae"
},
{
"path": "protocol/dhcp.go",
"chars": 7192,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n * K"
},
{
"path": "protocol/dhcp_test.go",
"chars": 12459,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015-2019 Samjung Data Service, Inc. All rights reserved.\n * K"
},
{
"path": "protocol/ethernet.go",
"chars": 1884,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved. \n * Kitae"
},
{
"path": "protocol/icmp.go",
"chars": 2227,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved. \n * Kitae"
},
{
"path": "protocol/ipv4.go",
"chars": 3510,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "protocol/lldp.go",
"chars": 5107,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved. \n * Kitae"
},
{
"path": "protocol/tcp.go",
"chars": 3355,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "protocol/udp.go",
"chars": 2711,
"preview": "/*\n * Cherry - An OpenFlow Controller\n *\n * Copyright (C) 2015 Samjung Data Service, Inc. All rights reserved.\n * Kitae "
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/LICENSE",
"chars": 1080,
"preview": "Copyright (c) 2013-2016 Antoine Imbert\n\nThe MIT License\n\nPermission is hereby granted, free of charge, to any person obt"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/access_log_apache.go",
"chars": 6426,
"preview": "package rest\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"log\"\n\t\"net\"\n\t\"os\"\n\t\"strings\"\n\t\"text/template\"\n\t\"time\"\n)\n\n// TODO Future improve"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/access_log_json.go",
"chars": 2143,
"preview": "package rest\n\nimport (\n\t\"encoding/json\"\n\t\"log\"\n\t\"os\"\n\t\"time\"\n)\n\n// AccessLogJsonMiddleware produces the access log with "
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/api.go",
"chars": 2166,
"preview": "package rest\n\nimport (\n\t\"net/http\"\n)\n\n// Api defines a stack of Middlewares and an App.\ntype Api struct {\n\tstack []Middl"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/auth_basic.go",
"chars": 2703,
"preview": "package rest\n\nimport (\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"log\"\n\t\"net/http\"\n\t\"strings\"\n)\n\n// AuthBasicMiddleware provides a s"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/content_type_checker.go",
"chars": 1133,
"preview": "package rest\n\nimport (\n\t\"mime\"\n\t\"net/http\"\n\t\"strings\"\n)\n\n// ContentTypeCheckerMiddleware verifies the request Content-Ty"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/cors.go",
"chars": 4470,
"preview": "package rest\n\nimport (\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Possible improvements:\n// If AllowedMethods[\"*\"] then Acc"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/doc.go",
"chars": 1392,
"preview": "// A quick and easy way to setup a RESTful JSON API\n//\n// http://ant0ine.github.io/go-json-rest/\n//\n// Go-Json-Rest is a"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/gzip.go",
"chars": 3579,
"preview": "package rest\n\nimport (\n\t\"bufio\"\n\t\"compress/gzip\"\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n)\n\n// GzipMiddleware is responsible for c"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/if.go",
"chars": 1328,
"preview": "package rest\n\nimport (\n\t\"log\"\n)\n\n// IfMiddleware evaluates at runtime a condition based on the current request, and deci"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/json_indent.go",
"chars": 3059,
"preview": "package rest\n\nimport (\n\t\"bufio\"\n\t\"encoding/json\"\n\t\"net\"\n\t\"net/http\"\n)\n\n// JsonIndentMiddleware provides JSON encoding wi"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/jsonp.go",
"chars": 3112,
"preview": "package rest\n\nimport (\n\t\"bufio\"\n\t\"net\"\n\t\"net/http\"\n)\n\n// JsonpMiddleware provides JSONP responses on demand, based on th"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/middleware.go",
"chars": 2327,
"preview": "package rest\n\nimport (\n\t\"net/http\"\n)\n\n// HandlerFunc defines the handler function. It is the go-json-rest equivalent of "
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/powered_by.go",
"chars": 672,
"preview": "package rest\n\nconst xPoweredByDefault = \"go-json-rest\"\n\n// PoweredByMiddleware adds the \"X-Powered-By\" header to the HTT"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/recorder.go",
"chars": 2668,
"preview": "package rest\n\nimport (\n\t\"bufio\"\n\t\"net\"\n\t\"net/http\"\n)\n\n// RecorderMiddleware keeps a record of the HTTP status code of th"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/recover.go",
"chars": 1701,
"preview": "package rest\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\t\"runtime/debug\"\n)\n\n// RecoverMiddleware catches"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/request.go",
"chars": 3439,
"preview": "package rest\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\nvar (\n\t// ErrJsonPay"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/response.go",
"chars": 3885,
"preview": "package rest\n\nimport (\n\t\"bufio\"\n\t\"encoding/json\"\n\t\"net\"\n\t\"net/http\"\n)\n\n// A ResponseWriter interface dedicated to JSON H"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/route.go",
"chars": 3491,
"preview": "package rest\n\nimport (\n\t\"strings\"\n)\n\n// Route defines a route as consumed by the router. It can be instantiated directly"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/router.go",
"chars": 4842,
"preview": "package rest\n\nimport (\n\t\"errors\"\n\t\"github.com/ant0ine/go-json-rest/rest/trie\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\ntype "
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/status.go",
"chars": 3660,
"preview": "package rest\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n)\n\n// StatusMiddleware keeps track of various stats about the"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/timer.go",
"chars": 679,
"preview": "package rest\n\nimport (\n\t\"time\"\n)\n\n// TimerMiddleware computes the elapsed time spent during the execution of the wrapped"
},
{
"path": "vendor/github.com/ant0ine/go-json-rest/rest/trie/impl.go",
"chars": 9621,
"preview": "// Special Trie implementation for HTTP routing.\n//\n// This Trie implementation is designed to support strings that incl"
},
{
"path": "vendor/github.com/boombuler/barcode/.gitignore",
"chars": 9,
"preview": ".vscode/\n"
},
{
"path": "vendor/github.com/boombuler/barcode/LICENSE",
"chars": 1085,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Florian Sundermann\n\nPermission is hereby granted, free of charge, to any perso"
},
{
"path": "vendor/github.com/boombuler/barcode/README.md",
"chars": 1166,
"preview": "[](https://"
},
{
"path": "vendor/github.com/boombuler/barcode/barcode.go",
"chars": 1014,
"preview": "package barcode\n\nimport \"image\"\n\nconst (\n\tTypeAztec = \"Aztec\"\n\tTypeCodabar = \"Codabar\"\n\tTypeCode128 "
},
{
"path": "vendor/github.com/boombuler/barcode/qr/alphanumeric.go",
"chars": 1426,
"preview": "package qr\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/boombuler/barcode/utils\"\n)\n\nconst charSet string = \"01234"
},
{
"path": "vendor/github.com/boombuler/barcode/qr/automatic.go",
"chars": 573,
"preview": "package qr\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/boombuler/barcode/utils\"\n)\n\nfunc encodeAuto(content string, ecl ErrorCorrectio"
},
{
"path": "vendor/github.com/boombuler/barcode/qr/blocks.go",
"chars": 1784,
"preview": "package qr\n\ntype block struct {\n\tdata []byte\n\tecc []byte\n}\ntype blockList []*block\n\nfunc splitToBlocks(data <-chan byte"
},
{
"path": "vendor/github.com/boombuler/barcode/qr/encoder.go",
"chars": 15495,
"preview": "// Package qr can be used to create QR barcodes.\npackage qr\n\nimport (\n\t\"image\"\n\n\t\"github.com/boombuler/barcode\"\n\t\"github"
},
{
"path": "vendor/github.com/boombuler/barcode/qr/errorcorrection.go",
"chars": 639,
"preview": "package qr\n\nimport (\n\t\"github.com/boombuler/barcode/utils\"\n)\n\ntype errorCorrection struct {\n\trs *utils.ReedSolomonEncode"
},
{
"path": "vendor/github.com/boombuler/barcode/qr/numeric.go",
"chars": 1136,
"preview": "package qr\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"github.com/boombuler/barcode/utils\"\n)\n\nfunc encodeNumeric(content st"
},
{
"path": "vendor/github.com/boombuler/barcode/qr/qrcode.go",
"chars": 3309,
"preview": "package qr\n\nimport (\n\t\"image\"\n\t\"image/color\"\n\t\"math\"\n\n\t\"github.com/boombuler/barcode\"\n\t\"github.com/boombuler/barcode/uti"
},
{
"path": "vendor/github.com/boombuler/barcode/qr/unicode.go",
"chars": 681,
"preview": "package qr\n\nimport (\n\t\"errors\"\n\n\t\"github.com/boombuler/barcode/utils\"\n)\n\nfunc encodeUnicode(content string, ecl ErrorCor"
},
{
"path": "vendor/github.com/boombuler/barcode/qr/versioninfo.go",
"chars": 9417,
"preview": "package qr\n\nimport \"math\"\n\n// ErrorCorrectionLevel indicates the amount of \"backup data\" stored in the QR code\ntype Erro"
},
{
"path": "vendor/github.com/boombuler/barcode/scaledbarcode.go",
"chars": 2850,
"preview": "package barcode\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"image\"\n\t\"image/color\"\n\t\"math\"\n)\n\ntype wrapFunc func(x, y int) color.Color\n\n"
},
{
"path": "vendor/github.com/boombuler/barcode/utils/base1dcode.go",
"chars": 1285,
"preview": "// Package utils contain some utilities which are needed to create barcodes\npackage utils\n\nimport (\n\t\"image\"\n\t\"image/col"
},
{
"path": "vendor/github.com/boombuler/barcode/utils/bitlist.go",
"chars": 2552,
"preview": "package utils\n\n// BitList is a list that contains bits\ntype BitList struct {\n\tcount int\n\tdata []int32\n}\n\n// NewBitList "
},
{
"path": "vendor/github.com/boombuler/barcode/utils/galoisfield.go",
"chars": 1319,
"preview": "package utils\n\n// GaloisField encapsulates galois field arithmetics\ntype GaloisField struct {\n\tSize int\n\tBase int\n"
},
{
"path": "vendor/github.com/boombuler/barcode/utils/gfpoly.go",
"chars": 2817,
"preview": "package utils\n\ntype GFPoly struct {\n\tgf *GaloisField\n\tCoefficients []int\n}\n\nfunc (gp *GFPoly) Degree() int {\n\t"
},
{
"path": "vendor/github.com/boombuler/barcode/utils/reedsolomon.go",
"chars": 1091,
"preview": "package utils\n\nimport (\n\t\"sync\"\n)\n\ntype ReedSolomonEncoder struct {\n\tgf *GaloisField\n\tpolynomes []*GFPoly\n\tm "
},
{
"path": "vendor/github.com/boombuler/barcode/utils/runeint.go",
"chars": 458,
"preview": "package utils\n\n// RuneToInt converts a rune between '0' and '9' to an integer between 0 and 9\n// If the rune is outside "
},
{
"path": "vendor/github.com/davecgh/go-spew/LICENSE",
"chars": 766,
"preview": "ISC License\n\nCopyright (c) 2012-2016 Dave Collins <dave@davec.name>\n\nPermission to use, copy, modify, and/or distribute "
},
{
"path": "vendor/github.com/davecgh/go-spew/spew/bypass.go",
"chars": 4715,
"preview": "// Copyright (c) 2015-2016 Dave Collins <dave@davec.name>\n//\n// Permission to use, copy, modify, and distribute this sof"
},
{
"path": "vendor/github.com/davecgh/go-spew/spew/bypasssafe.go",
"chars": 1741,
"preview": "// Copyright (c) 2015-2016 Dave Collins <dave@davec.name>\n//\n// Permission to use, copy, modify, and distribute this sof"
},
{
"path": "vendor/github.com/davecgh/go-spew/spew/common.go",
"chars": 10364,
"preview": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this "
},
{
"path": "vendor/github.com/davecgh/go-spew/spew/config.go",
"chars": 12842,
"preview": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this "
},
{
"path": "vendor/github.com/davecgh/go-spew/spew/doc.go",
"chars": 8527,
"preview": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this "
},
{
"path": "vendor/github.com/davecgh/go-spew/spew/dump.go",
"chars": 13794,
"preview": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this "
},
{
"path": "vendor/github.com/davecgh/go-spew/spew/format.go",
"chars": 11314,
"preview": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this "
},
{
"path": "vendor/github.com/davecgh/go-spew/spew/spew.go",
"chars": 5969,
"preview": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this "
},
{
"path": "vendor/github.com/fsnotify/fsnotify/.gitignore",
"chars": 201,
"preview": "# Setup a Global .gitignore for OS and editor generated files:\n# https://help.github.com/articles/ignoring-files\n# git c"
},
{
"path": "vendor/github.com/fsnotify/fsnotify/.travis.yml",
"chars": 386,
"preview": "sudo: false\nlanguage: go\n\ngo:\n - 1.5.4\n - 1.6.1\n - tip\n\nmatrix:\n allow_failures:\n - go: tip\n\nbefore_script:\n - g"
},
{
"path": "vendor/github.com/fsnotify/fsnotify/AUTHORS",
"chars": 1479,
"preview": "# Names should be added to this file as\n#\tName or Organization <email address>\n# The email address is not required for o"
},
{
"path": "vendor/github.com/fsnotify/fsnotify/CHANGELOG.md",
"chars": 10615,
"preview": "# Changelog\n\n## v1.3.0 / 2016-04-19\n\n* Support linux/arm64 by [patching](https://go-review.googlesource.com/#/c/21971/) "
},
{
"path": "vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md",
"chars": 3973,
"preview": "# Contributing\n\n## Issues\n\n* Request features and report bugs using the [GitHub Issue Tracker](https://github.com/fsnoti"
},
{
"path": "vendor/github.com/fsnotify/fsnotify/LICENSE",
"chars": 1537,
"preview": "Copyright (c) 2012 The Go Authors. All rights reserved.\nCopyright (c) 2012 fsnotify Authors. All rights reserved.\n\nRedis"
},
{
"path": "vendor/github.com/fsnotify/fsnotify/README.md",
"chars": 3005,
"preview": "# File system notifications for Go\n\n[](https://godoc."
},
{
"path": "vendor/github.com/fsnotify/fsnotify/fen.go",
"chars": 935,
"preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "vendor/github.com/fsnotify/fsnotify/fsnotify.go",
"chars": 1472,
"preview": "// Copyright 2012 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
}
]
// ... and 498 more files (download for full content)
About this extraction
This page contains the full source code of the superkkt/cherry GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 698 files (6.1 MB), approximately 1.6M tokens, and a symbol index with 55883 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.