Revert "Switch to new vendor directory layout"
This reverts commit d5742209d3.
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
			
			
This commit is contained in:
		
							
								
								
									
										8
									
								
								vendor/github.com/vishvananda/netlink/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/vishvananda/netlink/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,8 +0,0 @@ | ||||
| language: go | ||||
| before_script: | ||||
|   # make sure we keep path in tact when we sudo | ||||
|   - sudo sed -i -e 's/^Defaults\tsecure_path.*$//' /etc/sudoers | ||||
|   # modprobe ip_gre or else the first gre device can't be deleted | ||||
|   - sudo modprobe ip_gre | ||||
| install: | ||||
|   - go get github.com/vishvananda/netns | ||||
							
								
								
									
										192
									
								
								vendor/github.com/vishvananda/netlink/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										192
									
								
								vendor/github.com/vishvananda/netlink/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,192 +0,0 @@ | ||||
|  | ||||
|                                  Apache License | ||||
|                            Version 2.0, January 2004 | ||||
|                         http://www.apache.org/licenses/ | ||||
|  | ||||
|    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||||
|  | ||||
|    1. Definitions. | ||||
|  | ||||
|       "License" shall mean the terms and conditions for use, reproduction, | ||||
|       and distribution as defined by Sections 1 through 9 of this document. | ||||
|  | ||||
|       "Licensor" shall mean the copyright owner or entity authorized by | ||||
|       the copyright owner that is granting the License. | ||||
|  | ||||
|       "Legal Entity" shall mean the union of the acting entity and all | ||||
|       other entities that control, are controlled by, or are under common | ||||
|       control with that entity. For the purposes of this definition, | ||||
|       "control" means (i) the power, direct or indirect, to cause the | ||||
|       direction or management of such entity, whether by contract or | ||||
|       otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||||
|       outstanding shares, or (iii) beneficial ownership of such entity. | ||||
|  | ||||
|       "You" (or "Your") shall mean an individual or Legal Entity | ||||
|       exercising permissions granted by this License. | ||||
|  | ||||
|       "Source" form shall mean the preferred form for making modifications, | ||||
|       including but not limited to software source code, documentation | ||||
|       source, and configuration files. | ||||
|  | ||||
|       "Object" form shall mean any form resulting from mechanical | ||||
|       transformation or translation of a Source form, including but | ||||
|       not limited to compiled object code, generated documentation, | ||||
|       and conversions to other media types. | ||||
|  | ||||
|       "Work" shall mean the work of authorship, whether in Source or | ||||
|       Object form, made available under the License, as indicated by a | ||||
|       copyright notice that is included in or attached to the work | ||||
|       (an example is provided in the Appendix below). | ||||
|  | ||||
|       "Derivative Works" shall mean any work, whether in Source or Object | ||||
|       form, that is based on (or derived from) the Work and for which the | ||||
|       editorial revisions, annotations, elaborations, or other modifications | ||||
|       represent, as a whole, an original work of authorship. For the purposes | ||||
|       of this License, Derivative Works shall not include works that remain | ||||
|       separable from, or merely link (or bind by name) to the interfaces of, | ||||
|       the Work and Derivative Works thereof. | ||||
|  | ||||
|       "Contribution" shall mean any work of authorship, including | ||||
|       the original version of the Work and any modifications or additions | ||||
|       to that Work or Derivative Works thereof, that is intentionally | ||||
|       submitted to Licensor for inclusion in the Work by the copyright owner | ||||
|       or by an individual or Legal Entity authorized to submit on behalf of | ||||
|       the copyright owner. For the purposes of this definition, "submitted" | ||||
|       means any form of electronic, verbal, or written communication sent | ||||
|       to the Licensor or its representatives, including but not limited to | ||||
|       communication on electronic mailing lists, source code control systems, | ||||
|       and issue tracking systems that are managed by, or on behalf of, the | ||||
|       Licensor for the purpose of discussing and improving the Work, but | ||||
|       excluding communication that is conspicuously marked or otherwise | ||||
|       designated in writing by the copyright owner as "Not a Contribution." | ||||
|  | ||||
|       "Contributor" shall mean Licensor and any individual or Legal Entity | ||||
|       on behalf of whom a Contribution has been received by Licensor and | ||||
|       subsequently incorporated within the Work. | ||||
|  | ||||
|    2. Grant of Copyright License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       copyright license to reproduce, prepare Derivative Works of, | ||||
|       publicly display, publicly perform, sublicense, and distribute the | ||||
|       Work and such Derivative Works in Source or Object form. | ||||
|  | ||||
|    3. Grant of Patent License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       (except as stated in this section) patent license to make, have made, | ||||
|       use, offer to sell, sell, import, and otherwise transfer the Work, | ||||
|       where such license applies only to those patent claims licensable | ||||
|       by such Contributor that are necessarily infringed by their | ||||
|       Contribution(s) alone or by combination of their Contribution(s) | ||||
|       with the Work to which such Contribution(s) was submitted. If You | ||||
|       institute patent litigation against any entity (including a | ||||
|       cross-claim or counterclaim in a lawsuit) alleging that the Work | ||||
|       or a Contribution incorporated within the Work constitutes direct | ||||
|       or contributory patent infringement, then any patent licenses | ||||
|       granted to You under this License for that Work shall terminate | ||||
|       as of the date such litigation is filed. | ||||
|  | ||||
|    4. Redistribution. You may reproduce and distribute copies of the | ||||
|       Work or Derivative Works thereof in any medium, with or without | ||||
|       modifications, and in Source or Object form, provided that You | ||||
|       meet the following conditions: | ||||
|  | ||||
|       (a) You must give any other recipients of the Work or | ||||
|           Derivative Works a copy of this License; and | ||||
|  | ||||
|       (b) You must cause any modified files to carry prominent notices | ||||
|           stating that You changed the files; and | ||||
|  | ||||
|       (c) You must retain, in the Source form of any Derivative Works | ||||
|           that You distribute, all copyright, patent, trademark, and | ||||
|           attribution notices from the Source form of the Work, | ||||
|           excluding those notices that do not pertain to any part of | ||||
|           the Derivative Works; and | ||||
|  | ||||
|       (d) If the Work includes a "NOTICE" text file as part of its | ||||
|           distribution, then any Derivative Works that You distribute must | ||||
|           include a readable copy of the attribution notices contained | ||||
|           within such NOTICE file, excluding those notices that do not | ||||
|           pertain to any part of the Derivative Works, in at least one | ||||
|           of the following places: within a NOTICE text file distributed | ||||
|           as part of the Derivative Works; within the Source form or | ||||
|           documentation, if provided along with the Derivative Works; or, | ||||
|           within a display generated by the Derivative Works, if and | ||||
|           wherever such third-party notices normally appear. The contents | ||||
|           of the NOTICE file are for informational purposes only and | ||||
|           do not modify the License. You may add Your own attribution | ||||
|           notices within Derivative Works that You distribute, alongside | ||||
|           or as an addendum to the NOTICE text from the Work, provided | ||||
|           that such additional attribution notices cannot be construed | ||||
|           as modifying the License. | ||||
|  | ||||
|       You may add Your own copyright statement to Your modifications and | ||||
|       may provide additional or different license terms and conditions | ||||
|       for use, reproduction, or distribution of Your modifications, or | ||||
|       for any such Derivative Works as a whole, provided Your use, | ||||
|       reproduction, and distribution of the Work otherwise complies with | ||||
|       the conditions stated in this License. | ||||
|  | ||||
|    5. Submission of Contributions. Unless You explicitly state otherwise, | ||||
|       any Contribution intentionally submitted for inclusion in the Work | ||||
|       by You to the Licensor shall be under the terms and conditions of | ||||
|       this License, without any additional terms or conditions. | ||||
|       Notwithstanding the above, nothing herein shall supersede or modify | ||||
|       the terms of any separate license agreement you may have executed | ||||
|       with Licensor regarding such Contributions. | ||||
|  | ||||
|    6. Trademarks. This License does not grant permission to use the trade | ||||
|       names, trademarks, service marks, or product names of the Licensor, | ||||
|       except as required for reasonable and customary use in describing the | ||||
|       origin of the Work and reproducing the content of the NOTICE file. | ||||
|  | ||||
|    7. Disclaimer of Warranty. Unless required by applicable law or | ||||
|       agreed to in writing, Licensor provides the Work (and each | ||||
|       Contributor provides its Contributions) on an "AS IS" BASIS, | ||||
|       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||||
|       implied, including, without limitation, any warranties or conditions | ||||
|       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||||
|       PARTICULAR PURPOSE. You are solely responsible for determining the | ||||
|       appropriateness of using or redistributing the Work and assume any | ||||
|       risks associated with Your exercise of permissions under this License. | ||||
|  | ||||
|    8. Limitation of Liability. In no event and under no legal theory, | ||||
|       whether in tort (including negligence), contract, or otherwise, | ||||
|       unless required by applicable law (such as deliberate and grossly | ||||
|       negligent acts) or agreed to in writing, shall any Contributor be | ||||
|       liable to You for damages, including any direct, indirect, special, | ||||
|       incidental, or consequential damages of any character arising as a | ||||
|       result of this License or out of the use or inability to use the | ||||
|       Work (including but not limited to damages for loss of goodwill, | ||||
|       work stoppage, computer failure or malfunction, or any and all | ||||
|       other commercial damages or losses), even if such Contributor | ||||
|       has been advised of the possibility of such damages. | ||||
|  | ||||
|    9. Accepting Warranty or Additional Liability. While redistributing | ||||
|       the Work or Derivative Works thereof, You may choose to offer, | ||||
|       and charge a fee for, acceptance of support, warranty, indemnity, | ||||
|       or other liability obligations and/or rights consistent with this | ||||
|       License. However, in accepting such obligations, You may act only | ||||
|       on Your own behalf and on Your sole responsibility, not on behalf | ||||
|       of any other Contributor, and only if You agree to indemnify, | ||||
|       defend, and hold each Contributor harmless for any liability | ||||
|       incurred by, or claims asserted against, such Contributor by reason | ||||
|       of your accepting any such warranty or additional liability. | ||||
|  | ||||
|    END OF TERMS AND CONDITIONS | ||||
|  | ||||
|    Copyright 2014 Vishvananda Ishaya. | ||||
|    Copyright 2014 Docker, Inc. | ||||
|  | ||||
|    Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|    you may not use this file except in compliance with the License. | ||||
|    You may obtain a copy of the License at | ||||
|  | ||||
|        http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
|    Unless required by applicable law or agreed to in writing, software | ||||
|    distributed under the License is distributed on an "AS IS" BASIS, | ||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|    See the License for the specific language governing permissions and | ||||
|    limitations under the License. | ||||
							
								
								
									
										29
									
								
								vendor/github.com/vishvananda/netlink/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/vishvananda/netlink/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,29 +0,0 @@ | ||||
| DIRS := \ | ||||
| 	. \ | ||||
| 	nl | ||||
|  | ||||
| DEPS = \ | ||||
| 	github.com/vishvananda/netns | ||||
|  | ||||
| uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1))) | ||||
| testdirs = $(call uniq,$(foreach d,$(1),$(dir $(wildcard $(d)/*_test.go)))) | ||||
| goroot = $(addprefix ../../../,$(1)) | ||||
| unroot = $(subst ../../../,,$(1)) | ||||
| fmt = $(addprefix fmt-,$(1)) | ||||
|  | ||||
| all: fmt test | ||||
|  | ||||
| $(call goroot,$(DEPS)): | ||||
| 	go get $(call unroot,$@) | ||||
|  | ||||
| .PHONY: $(call testdirs,$(DIRS)) | ||||
| $(call testdirs,$(DIRS)): | ||||
| 	sudo -E go test -v github.com/vishvananda/netlink/$@ | ||||
|  | ||||
| $(call fmt,$(call testdirs,$(DIRS))): | ||||
| 	! gofmt -l $(subst fmt-,,$@)/*.go | grep '' | ||||
|  | ||||
| .PHONY: fmt | ||||
| fmt: $(call fmt,$(call testdirs,$(DIRS))) | ||||
|  | ||||
| test: fmt $(call goroot,$(DEPS)) $(call testdirs,$(DIRS)) | ||||
							
								
								
									
										89
									
								
								vendor/github.com/vishvananda/netlink/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										89
									
								
								vendor/github.com/vishvananda/netlink/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,89 +0,0 @@ | ||||
| # netlink - netlink library for go # | ||||
|  | ||||
| [](https://travis-ci.org/vishvananda/netlink) [](https://godoc.org/github.com/vishvananda/netlink) | ||||
|  | ||||
| The netlink package provides a simple netlink library for go. Netlink | ||||
| is the interface a user-space program in linux uses to communicate with | ||||
| the kernel. It can be used to add and remove interfaces, set ip addresses | ||||
| and routes, and configure ipsec. Netlink communication requires elevated | ||||
| privileges, so in most cases this code needs to be run as root. Since | ||||
| low-level netlink messages are inscrutable at best, the library attempts | ||||
| to provide an api that is loosely modeled on the CLI provied by iproute2. | ||||
| Actions like `ip link add` will be accomplished via a similarly named | ||||
| function like AddLink(). This library began its life as a fork of the | ||||
| netlink functionality in | ||||
| [docker/libcontainer](https://github.com/docker/libcontainer) but was | ||||
| heavily rewritten to improve testability, performance, and to add new | ||||
| functionality like ipsec xfrm handling. | ||||
|  | ||||
| ## Local Build and Test ## | ||||
|  | ||||
| You can use go get command: | ||||
|  | ||||
|     go get github.com/vishvananda/netlink | ||||
|  | ||||
| Testing dependencies: | ||||
|  | ||||
|     go get github.com/vishvananda/netns | ||||
|  | ||||
| Testing (requires root): | ||||
|  | ||||
|     sudo -E go test github.com/vishvananda/netlink | ||||
|  | ||||
| ## Examples ## | ||||
|  | ||||
| Add a new bridge and add eth1 into it: | ||||
|  | ||||
| ```go | ||||
| package main | ||||
|  | ||||
| import ( | ||||
|     "net" | ||||
|     "github.com/vishvananda/netlink" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
|     la := netlink.NewLinkAttrs() | ||||
|     la.Name = "foo" | ||||
|     mybridge := &netlink.Bridge{la}} | ||||
|     _ := netlink.LinkAdd(mybridge) | ||||
|     eth1, _ := netlink.LinkByName("eth1") | ||||
|     netlink.LinkSetMaster(eth1, mybridge) | ||||
| } | ||||
|  | ||||
| ``` | ||||
| Note `NewLinkAttrs` constructor, it sets default values in structure. For now | ||||
| it sets only `TxQLen` to `-1`, so kernel will set default by itself. If you're | ||||
| using simple initialization(`LinkAttrs{Name: "foo"}`) `TxQLen` will be set to | ||||
| `0` unless you specify it like `LinkAttrs{Name: "foo", TxQLen: 1000}`. | ||||
|  | ||||
| Add a new ip address to loopback: | ||||
|  | ||||
| ```go | ||||
| package main | ||||
|  | ||||
| import ( | ||||
|     "net" | ||||
|     "github.com/vishvananda/netlink" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
|     lo, _ := netlink.LinkByName("lo") | ||||
|     addr, _ := netlink.ParseAddr("169.254.169.254/32") | ||||
|     netlink.AddrAdd(lo, addr) | ||||
| } | ||||
|  | ||||
| ``` | ||||
|  | ||||
| ## Future Work ## | ||||
|  | ||||
| Many pieces of netlink are not yet fully supported in the high-level | ||||
| interface. Aspects of virtually all of the high-level objects don't exist. | ||||
| Many of the underlying primitives are there, so its a matter of putting | ||||
| the right fields into the high-level objects and making sure that they | ||||
| are serialized and deserialized correctly in the Add and List methods. | ||||
|  | ||||
| There are also a few pieces of low level netlink functionality that still | ||||
| need to be implemented. Routing rules are not in place and some of the | ||||
| more advanced link types. Hopefully there is decent structure and testing | ||||
| in place to make these fairly straightforward to add. | ||||
							
								
								
									
										45
									
								
								vendor/github.com/vishvananda/netlink/addr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										45
									
								
								vendor/github.com/vishvananda/netlink/addr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,45 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // Addr represents an IP address from netlink. Netlink ip addresses | ||||
| // include a mask, so it stores the address as a net.IPNet. | ||||
| type Addr struct { | ||||
| 	*net.IPNet | ||||
| 	Label string | ||||
| 	Flags int | ||||
| 	Scope int | ||||
| } | ||||
|  | ||||
| // String returns $ip/$netmask $label | ||||
| func (a Addr) String() string { | ||||
| 	return strings.TrimSpace(fmt.Sprintf("%s %s", a.IPNet, a.Label)) | ||||
| } | ||||
|  | ||||
| // ParseAddr parses the string representation of an address in the | ||||
| // form $ip/$netmask $label. The label portion is optional | ||||
| func ParseAddr(s string) (*Addr, error) { | ||||
| 	label := "" | ||||
| 	parts := strings.Split(s, " ") | ||||
| 	if len(parts) > 1 { | ||||
| 		s = parts[0] | ||||
| 		label = parts[1] | ||||
| 	} | ||||
| 	m, err := ParseIPNet(s) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &Addr{IPNet: m, Label: label}, nil | ||||
| } | ||||
|  | ||||
| // Equal returns true if both Addrs have the same net.IPNet value. | ||||
| func (a Addr) Equal(x Addr) bool { | ||||
| 	sizea, _ := a.Mask.Size() | ||||
| 	sizeb, _ := x.Mask.Size() | ||||
| 	// ignore label for comparison | ||||
| 	return a.IP.Equal(x.IP) && sizea == sizeb | ||||
| } | ||||
							
								
								
									
										142
									
								
								vendor/github.com/vishvananda/netlink/addr_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										142
									
								
								vendor/github.com/vishvananda/netlink/addr_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,142 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"strings" | ||||
| 	"syscall" | ||||
|  | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
|  | ||||
| // IFA_FLAGS is a u32 attribute. | ||||
| const IFA_FLAGS = 0x8 | ||||
|  | ||||
| // AddrAdd will add an IP address to a link device. | ||||
| // Equivalent to: `ip addr add $addr dev $link` | ||||
| func AddrAdd(link Link, addr *Addr) error { | ||||
|  | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_NEWADDR, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) | ||||
| 	return addrHandle(link, addr, req) | ||||
| } | ||||
|  | ||||
| // AddrDel will delete an IP address from a link device. | ||||
| // Equivalent to: `ip addr del $addr dev $link` | ||||
| func AddrDel(link Link, addr *Addr) error { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_DELADDR, syscall.NLM_F_ACK) | ||||
| 	return addrHandle(link, addr, req) | ||||
| } | ||||
|  | ||||
| func addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error { | ||||
| 	base := link.Attrs() | ||||
| 	if addr.Label != "" && !strings.HasPrefix(addr.Label, base.Name) { | ||||
| 		return fmt.Errorf("label must begin with interface name") | ||||
| 	} | ||||
| 	ensureIndex(base) | ||||
|  | ||||
| 	family := nl.GetIPFamily(addr.IP) | ||||
|  | ||||
| 	msg := nl.NewIfAddrmsg(family) | ||||
| 	msg.Index = uint32(base.Index) | ||||
| 	msg.Scope = uint8(addr.Scope) | ||||
| 	prefixlen, _ := addr.Mask.Size() | ||||
| 	msg.Prefixlen = uint8(prefixlen) | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	var addrData []byte | ||||
| 	if family == FAMILY_V4 { | ||||
| 		addrData = addr.IP.To4() | ||||
| 	} else { | ||||
| 		addrData = addr.IP.To16() | ||||
| 	} | ||||
|  | ||||
| 	localData := nl.NewRtAttr(syscall.IFA_LOCAL, addrData) | ||||
| 	req.AddData(localData) | ||||
|  | ||||
| 	addressData := nl.NewRtAttr(syscall.IFA_ADDRESS, addrData) | ||||
| 	req.AddData(addressData) | ||||
|  | ||||
| 	if addr.Flags != 0 { | ||||
| 		b := make([]byte, 4) | ||||
| 		native.PutUint32(b, uint32(addr.Flags)) | ||||
| 		flagsData := nl.NewRtAttr(IFA_FLAGS, b) | ||||
| 		req.AddData(flagsData) | ||||
| 	} | ||||
|  | ||||
| 	if addr.Label != "" { | ||||
| 		labelData := nl.NewRtAttr(syscall.IFA_LABEL, nl.ZeroTerminated(addr.Label)) | ||||
| 		req.AddData(labelData) | ||||
| 	} | ||||
|  | ||||
| 	_, err := req.Execute(syscall.NETLINK_ROUTE, 0) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // AddrList gets a list of IP addresses in the system. | ||||
| // Equivalent to: `ip addr show`. | ||||
| // The list can be filtered by link and ip family. | ||||
| func AddrList(link Link, family int) ([]Addr, error) { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_GETADDR, syscall.NLM_F_DUMP) | ||||
| 	msg := nl.NewIfInfomsg(family) | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWADDR) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	index := 0 | ||||
| 	if link != nil { | ||||
| 		base := link.Attrs() | ||||
| 		ensureIndex(base) | ||||
| 		index = base.Index | ||||
| 	} | ||||
|  | ||||
| 	var res []Addr | ||||
| 	for _, m := range msgs { | ||||
| 		msg := nl.DeserializeIfAddrmsg(m) | ||||
|  | ||||
| 		if link != nil && msg.Index != uint32(index) { | ||||
| 			// Ignore messages from other interfaces | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		attrs, err := nl.ParseRouteAttr(m[msg.Len():]) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		var local, dst *net.IPNet | ||||
| 		var addr Addr | ||||
| 		for _, attr := range attrs { | ||||
| 			switch attr.Attr.Type { | ||||
| 			case syscall.IFA_ADDRESS: | ||||
| 				dst = &net.IPNet{ | ||||
| 					IP:   attr.Value, | ||||
| 					Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)), | ||||
| 				} | ||||
| 			case syscall.IFA_LOCAL: | ||||
| 				local = &net.IPNet{ | ||||
| 					IP:   attr.Value, | ||||
| 					Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)), | ||||
| 				} | ||||
| 			case syscall.IFA_LABEL: | ||||
| 				addr.Label = string(attr.Value[:len(attr.Value)-1]) | ||||
| 			case IFA_FLAGS: | ||||
| 				addr.Flags = int(native.Uint32(attr.Value[0:4])) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// IFA_LOCAL should be there but if not, fall back to IFA_ADDRESS | ||||
| 		if local != nil { | ||||
| 			addr.IPNet = local | ||||
| 		} else { | ||||
| 			addr.IPNet = dst | ||||
| 		} | ||||
| 		addr.Scope = int(msg.Scope) | ||||
|  | ||||
| 		res = append(res, addr) | ||||
| 	} | ||||
|  | ||||
| 	return res, nil | ||||
| } | ||||
							
								
								
									
										110
									
								
								vendor/github.com/vishvananda/netlink/class.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										110
									
								
								vendor/github.com/vishvananda/netlink/class.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,110 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| ) | ||||
|  | ||||
| type Class interface { | ||||
| 	Attrs() *ClassAttrs | ||||
| 	Type() string | ||||
| } | ||||
|  | ||||
| // Class represents a netlink class. A filter is associated with a link, | ||||
| // has a handle and a parent. The root filter of a device should have a | ||||
| // parent == HANDLE_ROOT. | ||||
| type ClassAttrs struct { | ||||
| 	LinkIndex int | ||||
| 	Handle    uint32 | ||||
| 	Parent    uint32 | ||||
| 	Leaf      uint32 | ||||
| } | ||||
|  | ||||
| func (q ClassAttrs) String() string { | ||||
| 	return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Leaf: %s}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Leaf) | ||||
| } | ||||
|  | ||||
| type HtbClassAttrs struct { | ||||
| 	// TODO handle all attributes | ||||
| 	Rate    uint64 | ||||
| 	Ceil    uint64 | ||||
| 	Buffer  uint32 | ||||
| 	Cbuffer uint32 | ||||
| 	Quantum uint32 | ||||
| 	Level   uint32 | ||||
| 	Prio    uint32 | ||||
| } | ||||
|  | ||||
| func (q HtbClassAttrs) String() string { | ||||
| 	return fmt.Sprintf("{Rate: %d, Ceil: %d, Buffer: %d, Cbuffer: %d}", q.Rate, q.Ceil, q.Buffer, q.Cbuffer) | ||||
| } | ||||
|  | ||||
| // Htb class | ||||
| type HtbClass struct { | ||||
| 	ClassAttrs | ||||
| 	Rate    uint64 | ||||
| 	Ceil    uint64 | ||||
| 	Buffer  uint32 | ||||
| 	Cbuffer uint32 | ||||
| 	Quantum uint32 | ||||
| 	Level   uint32 | ||||
| 	Prio    uint32 | ||||
| } | ||||
|  | ||||
| func NewHtbClass(attrs ClassAttrs, cattrs HtbClassAttrs) *HtbClass { | ||||
| 	mtu := 1600 | ||||
| 	rate := cattrs.Rate / 8 | ||||
| 	ceil := cattrs.Ceil / 8 | ||||
| 	buffer := cattrs.Buffer | ||||
| 	cbuffer := cattrs.Cbuffer | ||||
| 	if ceil == 0 { | ||||
| 		ceil = rate | ||||
| 	} | ||||
|  | ||||
| 	if buffer == 0 { | ||||
| 		buffer = uint32(float64(rate)/Hz() + float64(mtu)) | ||||
| 	} | ||||
| 	buffer = uint32(Xmittime(rate, buffer)) | ||||
|  | ||||
| 	if cbuffer == 0 { | ||||
| 		cbuffer = uint32(float64(ceil)/Hz() + float64(mtu)) | ||||
| 	} | ||||
| 	cbuffer = uint32(Xmittime(ceil, cbuffer)) | ||||
|  | ||||
| 	return &HtbClass{ | ||||
| 		ClassAttrs: attrs, | ||||
| 		Rate:       rate, | ||||
| 		Ceil:       ceil, | ||||
| 		Buffer:     buffer, | ||||
| 		Cbuffer:    cbuffer, | ||||
| 		Quantum:    10, | ||||
| 		Level:      0, | ||||
| 		Prio:       0, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (q HtbClass) String() string { | ||||
| 	return fmt.Sprintf("{Rate: %d, Ceil: %d, Buffer: %d, Cbuffer: %d}", q.Rate, q.Ceil, q.Buffer, q.Cbuffer) | ||||
| } | ||||
|  | ||||
| func (class *HtbClass) Attrs() *ClassAttrs { | ||||
| 	return &class.ClassAttrs | ||||
| } | ||||
|  | ||||
| func (class *HtbClass) Type() string { | ||||
| 	return "htb" | ||||
| } | ||||
|  | ||||
| // GenericClass classes represent types that are not currently understood | ||||
| // by this netlink library. | ||||
| type GenericClass struct { | ||||
| 	ClassAttrs | ||||
| 	ClassType string | ||||
| } | ||||
|  | ||||
| func (class *GenericClass) Attrs() *ClassAttrs { | ||||
| 	return &class.ClassAttrs | ||||
| } | ||||
|  | ||||
| func (class *GenericClass) Type() string { | ||||
| 	return class.ClassType | ||||
| } | ||||
							
								
								
									
										168
									
								
								vendor/github.com/vishvananda/netlink/class_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										168
									
								
								vendor/github.com/vishvananda/netlink/class_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,168 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"syscall" | ||||
|  | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
|  | ||||
| // ClassDel will delete a class from the system. | ||||
| // Equivalent to: `tc class del $class` | ||||
| func ClassDel(class Class) error { | ||||
| 	return classModify(syscall.RTM_DELTCLASS, 0, class) | ||||
| } | ||||
|  | ||||
| // ClassChange will change a class in place | ||||
| // Equivalent to: `tc class change $class` | ||||
| // The parent and handle MUST NOT be changed. | ||||
|  | ||||
| func ClassChange(class Class) error { | ||||
| 	return classModify(syscall.RTM_NEWTCLASS, 0, class) | ||||
| } | ||||
|  | ||||
| // ClassReplace will replace a class to the system. | ||||
| // quivalent to: `tc class replace $class` | ||||
| // The handle MAY be changed. | ||||
| // If a class already exist with this parent/handle pair, the class is changed. | ||||
| // If a class does not already exist with this parent/handle, a new class is created. | ||||
| func ClassReplace(class Class) error { | ||||
| 	return classModify(syscall.RTM_NEWTCLASS, syscall.NLM_F_CREATE, class) | ||||
| } | ||||
|  | ||||
| // ClassAdd will add a class to the system. | ||||
| // Equivalent to: `tc class add $class` | ||||
| func ClassAdd(class Class) error { | ||||
| 	return classModify( | ||||
| 		syscall.RTM_NEWTCLASS, | ||||
| 		syscall.NLM_F_CREATE|syscall.NLM_F_EXCL, | ||||
| 		class, | ||||
| 	) | ||||
| } | ||||
|  | ||||
| func classModify(cmd, flags int, class Class) error { | ||||
| 	req := nl.NewNetlinkRequest(cmd, flags|syscall.NLM_F_ACK) | ||||
| 	base := class.Attrs() | ||||
| 	msg := &nl.TcMsg{ | ||||
| 		Family:  nl.FAMILY_ALL, | ||||
| 		Ifindex: int32(base.LinkIndex), | ||||
| 		Handle:  base.Handle, | ||||
| 		Parent:  base.Parent, | ||||
| 	} | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	if cmd != syscall.RTM_DELTCLASS { | ||||
| 		if err := classPayload(req, class); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	_, err := req.Execute(syscall.NETLINK_ROUTE, 0) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func classPayload(req *nl.NetlinkRequest, class Class) error { | ||||
| 	req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(class.Type()))) | ||||
|  | ||||
| 	options := nl.NewRtAttr(nl.TCA_OPTIONS, nil) | ||||
| 	if htb, ok := class.(*HtbClass); ok { | ||||
| 		opt := nl.TcHtbCopt{} | ||||
| 		opt.Rate.Rate = uint32(htb.Rate) | ||||
| 		opt.Ceil.Rate = uint32(htb.Ceil) | ||||
| 		opt.Buffer = htb.Buffer | ||||
| 		opt.Cbuffer = htb.Cbuffer | ||||
| 		opt.Quantum = htb.Quantum | ||||
| 		opt.Level = htb.Level | ||||
| 		opt.Prio = htb.Prio | ||||
| 		// TODO: Handle Debug properly. For now default to 0 | ||||
| 		nl.NewRtAttrChild(options, nl.TCA_HTB_PARMS, opt.Serialize()) | ||||
| 	} | ||||
| 	req.AddData(options) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // ClassList gets a list of classes in the system. | ||||
| // Equivalent to: `tc class show`. | ||||
| // Generally returns nothing if link and parent are not specified. | ||||
| func ClassList(link Link, parent uint32) ([]Class, error) { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_GETTCLASS, syscall.NLM_F_DUMP) | ||||
| 	msg := &nl.TcMsg{ | ||||
| 		Family: nl.FAMILY_ALL, | ||||
| 		Parent: parent, | ||||
| 	} | ||||
| 	if link != nil { | ||||
| 		base := link.Attrs() | ||||
| 		ensureIndex(base) | ||||
| 		msg.Ifindex = int32(base.Index) | ||||
| 	} | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWTCLASS) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var res []Class | ||||
| 	for _, m := range msgs { | ||||
| 		msg := nl.DeserializeTcMsg(m) | ||||
|  | ||||
| 		attrs, err := nl.ParseRouteAttr(m[msg.Len():]) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		base := ClassAttrs{ | ||||
| 			LinkIndex: int(msg.Ifindex), | ||||
| 			Handle:    msg.Handle, | ||||
| 			Parent:    msg.Parent, | ||||
| 		} | ||||
|  | ||||
| 		var class Class | ||||
| 		classType := "" | ||||
| 		for _, attr := range attrs { | ||||
| 			switch attr.Attr.Type { | ||||
| 			case nl.TCA_KIND: | ||||
| 				classType = string(attr.Value[:len(attr.Value)-1]) | ||||
| 				switch classType { | ||||
| 				case "htb": | ||||
| 					class = &HtbClass{} | ||||
| 				default: | ||||
| 					class = &GenericClass{ClassType: classType} | ||||
| 				} | ||||
| 			case nl.TCA_OPTIONS: | ||||
| 				switch classType { | ||||
| 				case "htb": | ||||
| 					data, err := nl.ParseRouteAttr(attr.Value) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 					_, err = parseHtbClassData(class, data) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		*class.Attrs() = base | ||||
| 		res = append(res, class) | ||||
| 	} | ||||
|  | ||||
| 	return res, nil | ||||
| } | ||||
|  | ||||
| func parseHtbClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, error) { | ||||
| 	htb := class.(*HtbClass) | ||||
| 	detailed := false | ||||
| 	for _, datum := range data { | ||||
| 		switch datum.Attr.Type { | ||||
| 		case nl.TCA_HTB_PARMS: | ||||
| 			opt := nl.DeserializeTcHtbCopt(datum.Value) | ||||
| 			htb.Rate = uint64(opt.Rate.Rate) | ||||
| 			htb.Ceil = uint64(opt.Ceil.Rate) | ||||
| 			htb.Buffer = opt.Buffer | ||||
| 			htb.Cbuffer = opt.Cbuffer | ||||
| 			htb.Quantum = opt.Quantum | ||||
| 			htb.Level = opt.Level | ||||
| 			htb.Prio = opt.Prio | ||||
| 		} | ||||
| 	} | ||||
| 	return detailed, nil | ||||
| } | ||||
							
								
								
									
										140
									
								
								vendor/github.com/vishvananda/netlink/filter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										140
									
								
								vendor/github.com/vishvananda/netlink/filter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,140 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
|  | ||||
| type Filter interface { | ||||
| 	Attrs() *FilterAttrs | ||||
| 	Type() string | ||||
| } | ||||
|  | ||||
| // Filter represents a netlink filter. A filter is associated with a link, | ||||
| // has a handle and a parent. The root filter of a device should have a | ||||
| // parent == HANDLE_ROOT. | ||||
| type FilterAttrs struct { | ||||
| 	LinkIndex int | ||||
| 	Handle    uint32 | ||||
| 	Parent    uint32 | ||||
| 	Priority  uint16 // lower is higher priority | ||||
| 	Protocol  uint16 // syscall.ETH_P_* | ||||
| } | ||||
|  | ||||
| func (q FilterAttrs) String() string { | ||||
| 	return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Priority: %d, Protocol: %d}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Priority, q.Protocol) | ||||
| } | ||||
|  | ||||
| // U32 filters on many packet related properties | ||||
| type U32 struct { | ||||
| 	FilterAttrs | ||||
| 	// Currently only supports redirecting to another interface | ||||
| 	RedirIndex int | ||||
| } | ||||
|  | ||||
| func (filter *U32) Attrs() *FilterAttrs { | ||||
| 	return &filter.FilterAttrs | ||||
| } | ||||
|  | ||||
| func (filter *U32) Type() string { | ||||
| 	return "u32" | ||||
| } | ||||
|  | ||||
| type FilterFwAttrs struct { | ||||
| 	ClassId   uint32 | ||||
| 	InDev     string | ||||
| 	Mask      uint32 | ||||
| 	Index     uint32 | ||||
| 	Buffer    uint32 | ||||
| 	Mtu       uint32 | ||||
| 	Mpu       uint16 | ||||
| 	Rate      uint32 | ||||
| 	AvRate    uint32 | ||||
| 	PeakRate  uint32 | ||||
| 	Action    int | ||||
| 	Overhead  uint16 | ||||
| 	LinkLayer int | ||||
| } | ||||
|  | ||||
| // FwFilter filters on firewall marks | ||||
| type Fw struct { | ||||
| 	FilterAttrs | ||||
| 	ClassId uint32 | ||||
| 	Police  nl.TcPolice | ||||
| 	InDev   string | ||||
| 	// TODO Action | ||||
| 	Mask   uint32 | ||||
| 	AvRate uint32 | ||||
| 	Rtab   [256]uint32 | ||||
| 	Ptab   [256]uint32 | ||||
| } | ||||
|  | ||||
| func NewFw(attrs FilterAttrs, fattrs FilterFwAttrs) (*Fw, error) { | ||||
| 	var rtab [256]uint32 | ||||
| 	var ptab [256]uint32 | ||||
| 	rcell_log := -1 | ||||
| 	pcell_log := -1 | ||||
| 	avrate := fattrs.AvRate / 8 | ||||
| 	police := nl.TcPolice{} | ||||
| 	police.Rate.Rate = fattrs.Rate / 8 | ||||
| 	police.PeakRate.Rate = fattrs.PeakRate / 8 | ||||
| 	buffer := fattrs.Buffer | ||||
| 	linklayer := nl.LINKLAYER_ETHERNET | ||||
|  | ||||
| 	if fattrs.LinkLayer != nl.LINKLAYER_UNSPEC { | ||||
| 		linklayer = fattrs.LinkLayer | ||||
| 	} | ||||
|  | ||||
| 	police.Action = int32(fattrs.Action) | ||||
| 	if police.Rate.Rate != 0 { | ||||
| 		police.Rate.Mpu = fattrs.Mpu | ||||
| 		police.Rate.Overhead = fattrs.Overhead | ||||
| 		if CalcRtable(&police.Rate, rtab, rcell_log, fattrs.Mtu, linklayer) < 0 { | ||||
| 			return nil, errors.New("TBF: failed to calculate rate table.") | ||||
| 		} | ||||
| 		police.Burst = uint32(Xmittime(uint64(police.Rate.Rate), uint32(buffer))) | ||||
| 	} | ||||
| 	police.Mtu = fattrs.Mtu | ||||
| 	if police.PeakRate.Rate != 0 { | ||||
| 		police.PeakRate.Mpu = fattrs.Mpu | ||||
| 		police.PeakRate.Overhead = fattrs.Overhead | ||||
| 		if CalcRtable(&police.PeakRate, ptab, pcell_log, fattrs.Mtu, linklayer) < 0 { | ||||
| 			return nil, errors.New("POLICE: failed to calculate peak rate table.") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return &Fw{ | ||||
| 		FilterAttrs: attrs, | ||||
| 		ClassId:     fattrs.ClassId, | ||||
| 		InDev:       fattrs.InDev, | ||||
| 		Mask:        fattrs.Mask, | ||||
| 		Police:      police, | ||||
| 		AvRate:      avrate, | ||||
| 		Rtab:        rtab, | ||||
| 		Ptab:        ptab, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| func (filter *Fw) Attrs() *FilterAttrs { | ||||
| 	return &filter.FilterAttrs | ||||
| } | ||||
|  | ||||
| func (filter *Fw) Type() string { | ||||
| 	return "fw" | ||||
| } | ||||
|  | ||||
| // GenericFilter filters represent types that are not currently understood | ||||
| // by this netlink library. | ||||
| type GenericFilter struct { | ||||
| 	FilterAttrs | ||||
| 	FilterType string | ||||
| } | ||||
|  | ||||
| func (filter *GenericFilter) Attrs() *FilterAttrs { | ||||
| 	return &filter.FilterAttrs | ||||
| } | ||||
|  | ||||
| func (filter *GenericFilter) Type() string { | ||||
| 	return filter.FilterType | ||||
| } | ||||
							
								
								
									
										322
									
								
								vendor/github.com/vishvananda/netlink/filter_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										322
									
								
								vendor/github.com/vishvananda/netlink/filter_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,322 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"fmt" | ||||
| 	"syscall" | ||||
|  | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
|  | ||||
| // FilterDel will delete a filter from the system. | ||||
| // Equivalent to: `tc filter del $filter` | ||||
| func FilterDel(filter Filter) error { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_DELTFILTER, syscall.NLM_F_ACK) | ||||
| 	base := filter.Attrs() | ||||
| 	msg := &nl.TcMsg{ | ||||
| 		Family:  nl.FAMILY_ALL, | ||||
| 		Ifindex: int32(base.LinkIndex), | ||||
| 		Handle:  base.Handle, | ||||
| 		Parent:  base.Parent, | ||||
| 		Info:    MakeHandle(base.Priority, nl.Swap16(base.Protocol)), | ||||
| 	} | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	_, err := req.Execute(syscall.NETLINK_ROUTE, 0) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // FilterAdd will add a filter to the system. | ||||
| // Equivalent to: `tc filter add $filter` | ||||
| func FilterAdd(filter Filter) error { | ||||
| 	native = nl.NativeEndian() | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_NEWTFILTER, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) | ||||
| 	base := filter.Attrs() | ||||
| 	msg := &nl.TcMsg{ | ||||
| 		Family:  nl.FAMILY_ALL, | ||||
| 		Ifindex: int32(base.LinkIndex), | ||||
| 		Handle:  base.Handle, | ||||
| 		Parent:  base.Parent, | ||||
| 		Info:    MakeHandle(base.Priority, nl.Swap16(base.Protocol)), | ||||
| 	} | ||||
| 	req.AddData(msg) | ||||
| 	req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(filter.Type()))) | ||||
|  | ||||
| 	options := nl.NewRtAttr(nl.TCA_OPTIONS, nil) | ||||
| 	if u32, ok := filter.(*U32); ok { | ||||
| 		// match all | ||||
| 		sel := nl.TcU32Sel{ | ||||
| 			Nkeys: 1, | ||||
| 			Flags: nl.TC_U32_TERMINAL, | ||||
| 		} | ||||
| 		sel.Keys = append(sel.Keys, nl.TcU32Key{}) | ||||
| 		nl.NewRtAttrChild(options, nl.TCA_U32_SEL, sel.Serialize()) | ||||
| 		actions := nl.NewRtAttrChild(options, nl.TCA_U32_ACT, nil) | ||||
| 		table := nl.NewRtAttrChild(actions, nl.TCA_ACT_TAB, nil) | ||||
| 		nl.NewRtAttrChild(table, nl.TCA_KIND, nl.ZeroTerminated("mirred")) | ||||
| 		// redirect to other interface | ||||
| 		mir := nl.TcMirred{ | ||||
| 			Action:  nl.TC_ACT_STOLEN, | ||||
| 			Eaction: nl.TCA_EGRESS_REDIR, | ||||
| 			Ifindex: uint32(u32.RedirIndex), | ||||
| 		} | ||||
| 		aopts := nl.NewRtAttrChild(table, nl.TCA_OPTIONS, nil) | ||||
| 		nl.NewRtAttrChild(aopts, nl.TCA_MIRRED_PARMS, mir.Serialize()) | ||||
| 	} else if fw, ok := filter.(*Fw); ok { | ||||
| 		if fw.Mask != 0 { | ||||
| 			b := make([]byte, 4) | ||||
| 			native.PutUint32(b, fw.Mask) | ||||
| 			nl.NewRtAttrChild(options, nl.TCA_FW_MASK, b) | ||||
| 		} | ||||
| 		if fw.InDev != "" { | ||||
| 			nl.NewRtAttrChild(options, nl.TCA_FW_INDEV, nl.ZeroTerminated(fw.InDev)) | ||||
| 		} | ||||
| 		if (fw.Police != nl.TcPolice{}) { | ||||
|  | ||||
| 			police := nl.NewRtAttrChild(options, nl.TCA_FW_POLICE, nil) | ||||
| 			nl.NewRtAttrChild(police, nl.TCA_POLICE_TBF, fw.Police.Serialize()) | ||||
| 			if (fw.Police.Rate != nl.TcRateSpec{}) { | ||||
| 				payload := SerializeRtab(fw.Rtab) | ||||
| 				nl.NewRtAttrChild(police, nl.TCA_POLICE_RATE, payload) | ||||
| 			} | ||||
| 			if (fw.Police.PeakRate != nl.TcRateSpec{}) { | ||||
| 				payload := SerializeRtab(fw.Ptab) | ||||
| 				nl.NewRtAttrChild(police, nl.TCA_POLICE_PEAKRATE, payload) | ||||
| 			} | ||||
| 		} | ||||
| 		if fw.ClassId != 0 { | ||||
| 			b := make([]byte, 4) | ||||
| 			native.PutUint32(b, fw.ClassId) | ||||
| 			nl.NewRtAttrChild(options, nl.TCA_FW_CLASSID, b) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	req.AddData(options) | ||||
| 	_, err := req.Execute(syscall.NETLINK_ROUTE, 0) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // FilterList gets a list of filters in the system. | ||||
| // Equivalent to: `tc filter show`. | ||||
| // Generally retunrs nothing if link and parent are not specified. | ||||
| func FilterList(link Link, parent uint32) ([]Filter, error) { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_GETTFILTER, syscall.NLM_F_DUMP) | ||||
| 	msg := &nl.TcMsg{ | ||||
| 		Family: nl.FAMILY_ALL, | ||||
| 		Parent: parent, | ||||
| 	} | ||||
| 	if link != nil { | ||||
| 		base := link.Attrs() | ||||
| 		ensureIndex(base) | ||||
| 		msg.Ifindex = int32(base.Index) | ||||
| 	} | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWTFILTER) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var res []Filter | ||||
| 	for _, m := range msgs { | ||||
| 		msg := nl.DeserializeTcMsg(m) | ||||
|  | ||||
| 		attrs, err := nl.ParseRouteAttr(m[msg.Len():]) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		base := FilterAttrs{ | ||||
| 			LinkIndex: int(msg.Ifindex), | ||||
| 			Handle:    msg.Handle, | ||||
| 			Parent:    msg.Parent, | ||||
| 		} | ||||
| 		base.Priority, base.Protocol = MajorMinor(msg.Info) | ||||
| 		base.Protocol = nl.Swap16(base.Protocol) | ||||
|  | ||||
| 		var filter Filter | ||||
| 		filterType := "" | ||||
| 		detailed := false | ||||
| 		for _, attr := range attrs { | ||||
| 			switch attr.Attr.Type { | ||||
| 			case nl.TCA_KIND: | ||||
| 				filterType = string(attr.Value[:len(attr.Value)-1]) | ||||
| 				switch filterType { | ||||
| 				case "u32": | ||||
| 					filter = &U32{} | ||||
| 				case "fw": | ||||
| 					filter = &Fw{} | ||||
| 				default: | ||||
| 					filter = &GenericFilter{FilterType: filterType} | ||||
| 				} | ||||
| 			case nl.TCA_OPTIONS: | ||||
| 				switch filterType { | ||||
| 				case "u32": | ||||
| 					data, err := nl.ParseRouteAttr(attr.Value) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 					detailed, err = parseU32Data(filter, data) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 				case "fw": | ||||
| 					data, err := nl.ParseRouteAttr(attr.Value) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 					detailed, err = parseFwData(filter, data) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		// only return the detailed version of the filter | ||||
| 		if detailed { | ||||
| 			*filter.Attrs() = base | ||||
| 			res = append(res, filter) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return res, nil | ||||
| } | ||||
|  | ||||
| func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) { | ||||
| 	native = nl.NativeEndian() | ||||
| 	u32 := filter.(*U32) | ||||
| 	detailed := false | ||||
| 	for _, datum := range data { | ||||
| 		switch datum.Attr.Type { | ||||
| 		case nl.TCA_U32_SEL: | ||||
| 			detailed = true | ||||
| 			sel := nl.DeserializeTcU32Sel(datum.Value) | ||||
| 			// only parse if we have a very basic redirect | ||||
| 			if sel.Flags&nl.TC_U32_TERMINAL == 0 || sel.Nkeys != 1 { | ||||
| 				return detailed, nil | ||||
| 			} | ||||
| 		case nl.TCA_U32_ACT: | ||||
| 			table, err := nl.ParseRouteAttr(datum.Value) | ||||
| 			if err != nil { | ||||
| 				return detailed, err | ||||
| 			} | ||||
| 			if len(table) != 1 || table[0].Attr.Type != nl.TCA_ACT_TAB { | ||||
| 				return detailed, fmt.Errorf("Action table not formed properly") | ||||
| 			} | ||||
| 			aattrs, err := nl.ParseRouteAttr(table[0].Value) | ||||
| 			for _, aattr := range aattrs { | ||||
| 				switch aattr.Attr.Type { | ||||
| 				case nl.TCA_KIND: | ||||
| 					actionType := string(aattr.Value[:len(aattr.Value)-1]) | ||||
| 					// only parse if the action is mirred | ||||
| 					if actionType != "mirred" { | ||||
| 						return detailed, nil | ||||
| 					} | ||||
| 				case nl.TCA_OPTIONS: | ||||
| 					adata, err := nl.ParseRouteAttr(aattr.Value) | ||||
| 					if err != nil { | ||||
| 						return detailed, err | ||||
| 					} | ||||
| 					for _, adatum := range adata { | ||||
| 						switch adatum.Attr.Type { | ||||
| 						case nl.TCA_MIRRED_PARMS: | ||||
| 							mir := nl.DeserializeTcMirred(adatum.Value) | ||||
| 							u32.RedirIndex = int(mir.Ifindex) | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return detailed, nil | ||||
| } | ||||
|  | ||||
| func parseFwData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) { | ||||
| 	native = nl.NativeEndian() | ||||
| 	fw := filter.(*Fw) | ||||
| 	detailed := true | ||||
| 	for _, datum := range data { | ||||
| 		switch datum.Attr.Type { | ||||
| 		case nl.TCA_FW_MASK: | ||||
| 			fw.Mask = native.Uint32(datum.Value[0:4]) | ||||
| 		case nl.TCA_FW_CLASSID: | ||||
| 			fw.ClassId = native.Uint32(datum.Value[0:4]) | ||||
| 		case nl.TCA_FW_INDEV: | ||||
| 			fw.InDev = string(datum.Value[:len(datum.Value)-1]) | ||||
| 		case nl.TCA_FW_POLICE: | ||||
| 			adata, _ := nl.ParseRouteAttr(datum.Value) | ||||
| 			for _, aattr := range adata { | ||||
| 				switch aattr.Attr.Type { | ||||
| 				case nl.TCA_POLICE_TBF: | ||||
| 					fw.Police = *nl.DeserializeTcPolice(aattr.Value) | ||||
| 				case nl.TCA_POLICE_RATE: | ||||
| 					fw.Rtab = DeserializeRtab(aattr.Value) | ||||
| 				case nl.TCA_POLICE_PEAKRATE: | ||||
| 					fw.Ptab = DeserializeRtab(aattr.Value) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return detailed, nil | ||||
| } | ||||
|  | ||||
| func AlignToAtm(size uint) uint { | ||||
| 	var linksize, cells int | ||||
| 	cells = int(size / nl.ATM_CELL_PAYLOAD) | ||||
| 	if (size % nl.ATM_CELL_PAYLOAD) > 0 { | ||||
| 		cells++ | ||||
| 	} | ||||
| 	linksize = cells * nl.ATM_CELL_SIZE | ||||
| 	return uint(linksize) | ||||
| } | ||||
|  | ||||
| func AdjustSize(sz uint, mpu uint, linklayer int) uint { | ||||
| 	if sz < mpu { | ||||
| 		sz = mpu | ||||
| 	} | ||||
| 	switch linklayer { | ||||
| 	case nl.LINKLAYER_ATM: | ||||
| 		return AlignToAtm(sz) | ||||
| 	default: | ||||
| 		return sz | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func CalcRtable(rate *nl.TcRateSpec, rtab [256]uint32, cell_log int, mtu uint32, linklayer int) int { | ||||
| 	bps := rate.Rate | ||||
| 	mpu := rate.Mpu | ||||
| 	var sz uint | ||||
| 	if mtu == 0 { | ||||
| 		mtu = 2047 | ||||
| 	} | ||||
| 	if cell_log < 0 { | ||||
| 		cell_log = 0 | ||||
| 		for (mtu >> uint(cell_log)) > 255 { | ||||
| 			cell_log++ | ||||
| 		} | ||||
| 	} | ||||
| 	for i := 0; i < 256; i++ { | ||||
| 		sz = AdjustSize(uint((i+1)<<uint32(cell_log)), uint(mpu), linklayer) | ||||
| 		rtab[i] = uint32(Xmittime(uint64(bps), uint32(sz))) | ||||
| 	} | ||||
| 	rate.CellAlign = -1 | ||||
| 	rate.CellLog = uint8(cell_log) | ||||
| 	rate.Linklayer = uint8(linklayer & nl.TC_LINKLAYER_MASK) | ||||
| 	return cell_log | ||||
| } | ||||
|  | ||||
| func DeserializeRtab(b []byte) [256]uint32 { | ||||
| 	var rtab [256]uint32 | ||||
| 	native := nl.NativeEndian() | ||||
| 	r := bytes.NewReader(b) | ||||
| 	_ = binary.Read(r, native, &rtab) | ||||
| 	return rtab | ||||
| } | ||||
|  | ||||
| func SerializeRtab(rtab [256]uint32) []byte { | ||||
| 	native := nl.NativeEndian() | ||||
| 	var w bytes.Buffer | ||||
| 	_ = binary.Write(&w, native, rtab) | ||||
| 	return w.Bytes() | ||||
| } | ||||
							
								
								
									
										559
									
								
								vendor/github.com/vishvananda/netlink/link.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										559
									
								
								vendor/github.com/vishvananda/netlink/link.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,559 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"syscall" | ||||
| ) | ||||
|  | ||||
| // Link represents a link device from netlink. Shared link attributes | ||||
| // like name may be retrieved using the Attrs() method. Unique data | ||||
| // can be retrieved by casting the object to the proper type. | ||||
| type Link interface { | ||||
| 	Attrs() *LinkAttrs | ||||
| 	Type() string | ||||
| } | ||||
|  | ||||
| type ( | ||||
| 	NsPid int | ||||
| 	NsFd  int | ||||
| ) | ||||
|  | ||||
| // LinkAttrs represents data shared by most link types | ||||
| type LinkAttrs struct { | ||||
| 	Index        int | ||||
| 	MTU          int | ||||
| 	TxQLen       int // Transmit Queue Length | ||||
| 	Name         string | ||||
| 	HardwareAddr net.HardwareAddr | ||||
| 	Flags        net.Flags | ||||
| 	ParentIndex  int         // index of the parent link device | ||||
| 	MasterIndex  int         // must be the index of a bridge | ||||
| 	Namespace    interface{} // nil | NsPid | NsFd | ||||
| 	Alias        string | ||||
| } | ||||
|  | ||||
| // NewLinkAttrs returns LinkAttrs structure filled with default values | ||||
| func NewLinkAttrs() LinkAttrs { | ||||
| 	return LinkAttrs{ | ||||
| 		TxQLen: -1, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Device links cannot be created via netlink. These links | ||||
| // are links created by udev like 'lo' and 'etho0' | ||||
| type Device struct { | ||||
| 	LinkAttrs | ||||
| } | ||||
|  | ||||
| func (device *Device) Attrs() *LinkAttrs { | ||||
| 	return &device.LinkAttrs | ||||
| } | ||||
|  | ||||
| func (device *Device) Type() string { | ||||
| 	return "device" | ||||
| } | ||||
|  | ||||
| // Dummy links are dummy ethernet devices | ||||
| type Dummy struct { | ||||
| 	LinkAttrs | ||||
| } | ||||
|  | ||||
| func (dummy *Dummy) Attrs() *LinkAttrs { | ||||
| 	return &dummy.LinkAttrs | ||||
| } | ||||
|  | ||||
| func (dummy *Dummy) Type() string { | ||||
| 	return "dummy" | ||||
| } | ||||
|  | ||||
| // Ifb links are advanced dummy devices for packet filtering | ||||
| type Ifb struct { | ||||
| 	LinkAttrs | ||||
| } | ||||
|  | ||||
| func (ifb *Ifb) Attrs() *LinkAttrs { | ||||
| 	return &ifb.LinkAttrs | ||||
| } | ||||
|  | ||||
| func (ifb *Ifb) Type() string { | ||||
| 	return "ifb" | ||||
| } | ||||
|  | ||||
| // Bridge links are simple linux bridges | ||||
| type Bridge struct { | ||||
| 	LinkAttrs | ||||
| } | ||||
|  | ||||
| func (bridge *Bridge) Attrs() *LinkAttrs { | ||||
| 	return &bridge.LinkAttrs | ||||
| } | ||||
|  | ||||
| func (bridge *Bridge) Type() string { | ||||
| 	return "bridge" | ||||
| } | ||||
|  | ||||
| // Vlan links have ParentIndex set in their Attrs() | ||||
| type Vlan struct { | ||||
| 	LinkAttrs | ||||
| 	VlanId int | ||||
| } | ||||
|  | ||||
| func (vlan *Vlan) Attrs() *LinkAttrs { | ||||
| 	return &vlan.LinkAttrs | ||||
| } | ||||
|  | ||||
| func (vlan *Vlan) Type() string { | ||||
| 	return "vlan" | ||||
| } | ||||
|  | ||||
| type MacvlanMode uint16 | ||||
|  | ||||
| const ( | ||||
| 	MACVLAN_MODE_DEFAULT MacvlanMode = iota | ||||
| 	MACVLAN_MODE_PRIVATE | ||||
| 	MACVLAN_MODE_VEPA | ||||
| 	MACVLAN_MODE_BRIDGE | ||||
| 	MACVLAN_MODE_PASSTHRU | ||||
| 	MACVLAN_MODE_SOURCE | ||||
| ) | ||||
|  | ||||
| // Macvlan links have ParentIndex set in their Attrs() | ||||
| type Macvlan struct { | ||||
| 	LinkAttrs | ||||
| 	Mode MacvlanMode | ||||
| } | ||||
|  | ||||
| func (macvlan *Macvlan) Attrs() *LinkAttrs { | ||||
| 	return &macvlan.LinkAttrs | ||||
| } | ||||
|  | ||||
| func (macvlan *Macvlan) Type() string { | ||||
| 	return "macvlan" | ||||
| } | ||||
|  | ||||
| // Macvtap - macvtap is a virtual interfaces based on macvlan | ||||
| type Macvtap struct { | ||||
| 	Macvlan | ||||
| } | ||||
|  | ||||
| func (macvtap Macvtap) Type() string { | ||||
| 	return "macvtap" | ||||
| } | ||||
|  | ||||
| type TuntapMode uint16 | ||||
|  | ||||
| const ( | ||||
| 	TUNTAP_MODE_TUN TuntapMode = syscall.IFF_TUN | ||||
| 	TUNTAP_MODE_TAP TuntapMode = syscall.IFF_TAP | ||||
| ) | ||||
|  | ||||
| // Tuntap links created via /dev/tun/tap, but can be destroyed via netlink | ||||
| type Tuntap struct { | ||||
| 	LinkAttrs | ||||
| 	Mode TuntapMode | ||||
| } | ||||
|  | ||||
| func (tuntap *Tuntap) Attrs() *LinkAttrs { | ||||
| 	return &tuntap.LinkAttrs | ||||
| } | ||||
|  | ||||
| func (tuntap *Tuntap) Type() string { | ||||
| 	return "tuntap" | ||||
| } | ||||
|  | ||||
| // Veth devices must specify PeerName on create | ||||
| type Veth struct { | ||||
| 	LinkAttrs | ||||
| 	PeerName string // veth on create only | ||||
| } | ||||
|  | ||||
| func (veth *Veth) Attrs() *LinkAttrs { | ||||
| 	return &veth.LinkAttrs | ||||
| } | ||||
|  | ||||
| func (veth *Veth) Type() string { | ||||
| 	return "veth" | ||||
| } | ||||
|  | ||||
| // GenericLink links represent types that are not currently understood | ||||
| // by this netlink library. | ||||
| type GenericLink struct { | ||||
| 	LinkAttrs | ||||
| 	LinkType string | ||||
| } | ||||
|  | ||||
| func (generic *GenericLink) Attrs() *LinkAttrs { | ||||
| 	return &generic.LinkAttrs | ||||
| } | ||||
|  | ||||
| func (generic *GenericLink) Type() string { | ||||
| 	return generic.LinkType | ||||
| } | ||||
|  | ||||
| type Vxlan struct { | ||||
| 	LinkAttrs | ||||
| 	VxlanId      int | ||||
| 	VtepDevIndex int | ||||
| 	SrcAddr      net.IP | ||||
| 	Group        net.IP | ||||
| 	TTL          int | ||||
| 	TOS          int | ||||
| 	Learning     bool | ||||
| 	Proxy        bool | ||||
| 	RSC          bool | ||||
| 	L2miss       bool | ||||
| 	L3miss       bool | ||||
| 	NoAge        bool | ||||
| 	GBP          bool | ||||
| 	Age          int | ||||
| 	Limit        int | ||||
| 	Port         int | ||||
| 	PortLow      int | ||||
| 	PortHigh     int | ||||
| } | ||||
|  | ||||
| func (vxlan *Vxlan) Attrs() *LinkAttrs { | ||||
| 	return &vxlan.LinkAttrs | ||||
| } | ||||
|  | ||||
| func (vxlan *Vxlan) Type() string { | ||||
| 	return "vxlan" | ||||
| } | ||||
|  | ||||
| type IPVlanMode uint16 | ||||
|  | ||||
| const ( | ||||
| 	IPVLAN_MODE_L2 IPVlanMode = iota | ||||
| 	IPVLAN_MODE_L3 | ||||
| 	IPVLAN_MODE_MAX | ||||
| ) | ||||
|  | ||||
| type IPVlan struct { | ||||
| 	LinkAttrs | ||||
| 	Mode IPVlanMode | ||||
| } | ||||
|  | ||||
| func (ipvlan *IPVlan) Attrs() *LinkAttrs { | ||||
| 	return &ipvlan.LinkAttrs | ||||
| } | ||||
|  | ||||
| func (ipvlan *IPVlan) Type() string { | ||||
| 	return "ipvlan" | ||||
| } | ||||
|  | ||||
| // BondMode type | ||||
| type BondMode int | ||||
|  | ||||
| func (b BondMode) String() string { | ||||
| 	s, ok := bondModeToString[b] | ||||
| 	if !ok { | ||||
| 		return fmt.Sprintf("BondMode(%d)", b) | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
|  | ||||
| // StringToBondMode returns bond mode, or uknonw is the s is invalid. | ||||
| func StringToBondMode(s string) BondMode { | ||||
| 	mode, ok := StringToBondModeMap[s] | ||||
| 	if !ok { | ||||
| 		return BOND_MODE_UNKNOWN | ||||
| 	} | ||||
| 	return mode | ||||
| } | ||||
|  | ||||
| // Possible BondMode | ||||
| const ( | ||||
| 	BOND_MODE_802_3AD BondMode = iota | ||||
| 	BOND_MODE_BALANCE_RR | ||||
| 	BOND_MODE_ACTIVE_BACKUP | ||||
| 	BOND_MODE_BALANCE_XOR | ||||
| 	BOND_MODE_BROADCAST | ||||
| 	BOND_MODE_BALANCE_TLB | ||||
| 	BOND_MODE_BALANCE_ALB | ||||
| 	BOND_MODE_UNKNOWN | ||||
| ) | ||||
|  | ||||
| var bondModeToString = map[BondMode]string{ | ||||
| 	BOND_MODE_802_3AD:       "802.3ad", | ||||
| 	BOND_MODE_BALANCE_RR:    "balance-rr", | ||||
| 	BOND_MODE_ACTIVE_BACKUP: "active-backup", | ||||
| 	BOND_MODE_BALANCE_XOR:   "balance-xor", | ||||
| 	BOND_MODE_BROADCAST:     "broadcast", | ||||
| 	BOND_MODE_BALANCE_TLB:   "balance-tlb", | ||||
| 	BOND_MODE_BALANCE_ALB:   "balance-alb", | ||||
| } | ||||
| var StringToBondModeMap = map[string]BondMode{ | ||||
| 	"802.3ad":       BOND_MODE_802_3AD, | ||||
| 	"balance-rr":    BOND_MODE_BALANCE_RR, | ||||
| 	"active-backup": BOND_MODE_ACTIVE_BACKUP, | ||||
| 	"balance-xor":   BOND_MODE_BALANCE_XOR, | ||||
| 	"broadcast":     BOND_MODE_BROADCAST, | ||||
| 	"balance-tlb":   BOND_MODE_BALANCE_TLB, | ||||
| 	"balance-alb":   BOND_MODE_BALANCE_ALB, | ||||
| } | ||||
|  | ||||
| // BondArpValidate type | ||||
| type BondArpValidate int | ||||
|  | ||||
| // Possible BondArpValidate value | ||||
| const ( | ||||
| 	BOND_ARP_VALIDATE_NONE BondArpValidate = iota | ||||
| 	BOND_ARP_VALIDATE_ACTIVE | ||||
| 	BOND_ARP_VALIDATE_BACKUP | ||||
| 	BOND_ARP_VALIDATE_ALL | ||||
| ) | ||||
|  | ||||
| // BondPrimaryReselect type | ||||
| type BondPrimaryReselect int | ||||
|  | ||||
| // Possible BondPrimaryReselect value | ||||
| const ( | ||||
| 	BOND_PRIMARY_RESELECT_ALWAYS BondPrimaryReselect = iota | ||||
| 	BOND_PRIMARY_RESELECT_BETTER | ||||
| 	BOND_PRIMARY_RESELECT_FAILURE | ||||
| ) | ||||
|  | ||||
| // BondArpAllTargets type | ||||
| type BondArpAllTargets int | ||||
|  | ||||
| // Possible BondArpAllTargets value | ||||
| const ( | ||||
| 	BOND_ARP_ALL_TARGETS_ANY BondArpAllTargets = iota | ||||
| 	BOND_ARP_ALL_TARGETS_ALL | ||||
| ) | ||||
|  | ||||
| // BondFailOverMac type | ||||
| type BondFailOverMac int | ||||
|  | ||||
| // Possible BondFailOverMac value | ||||
| const ( | ||||
| 	BOND_FAIL_OVER_MAC_NONE BondFailOverMac = iota | ||||
| 	BOND_FAIL_OVER_MAC_ACTIVE | ||||
| 	BOND_FAIL_OVER_MAC_FOLLOW | ||||
| ) | ||||
|  | ||||
| // BondXmitHashPolicy type | ||||
| type BondXmitHashPolicy int | ||||
|  | ||||
| func (b BondXmitHashPolicy) String() string { | ||||
| 	s, ok := bondXmitHashPolicyToString[b] | ||||
| 	if !ok { | ||||
| 		return fmt.Sprintf("XmitHashPolicy(%d)", b) | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
|  | ||||
| // StringToBondXmitHashPolicy returns bond lacp arte, or uknonw is the s is invalid. | ||||
| func StringToBondXmitHashPolicy(s string) BondXmitHashPolicy { | ||||
| 	lacp, ok := StringToBondXmitHashPolicyMap[s] | ||||
| 	if !ok { | ||||
| 		return BOND_XMIT_HASH_POLICY_UNKNOWN | ||||
| 	} | ||||
| 	return lacp | ||||
| } | ||||
|  | ||||
| // Possible BondXmitHashPolicy value | ||||
| const ( | ||||
| 	BOND_XMIT_HASH_POLICY_LAYER2 BondXmitHashPolicy = iota | ||||
| 	BOND_XMIT_HASH_POLICY_LAYER3_4 | ||||
| 	BOND_XMIT_HASH_POLICY_LAYER2_3 | ||||
| 	BOND_XMIT_HASH_POLICY_ENCAP2_3 | ||||
| 	BOND_XMIT_HASH_POLICY_ENCAP3_4 | ||||
| 	BOND_XMIT_HASH_POLICY_UNKNOWN | ||||
| ) | ||||
|  | ||||
| var bondXmitHashPolicyToString = map[BondXmitHashPolicy]string{ | ||||
| 	BOND_XMIT_HASH_POLICY_LAYER2:   "layer2", | ||||
| 	BOND_XMIT_HASH_POLICY_LAYER3_4: "layer3+4", | ||||
| 	BOND_XMIT_HASH_POLICY_LAYER2_3: "layer2+3", | ||||
| 	BOND_XMIT_HASH_POLICY_ENCAP2_3: "encap2+3", | ||||
| 	BOND_XMIT_HASH_POLICY_ENCAP3_4: "encap3+4", | ||||
| } | ||||
| var StringToBondXmitHashPolicyMap = map[string]BondXmitHashPolicy{ | ||||
| 	"layer2":   BOND_XMIT_HASH_POLICY_LAYER2, | ||||
| 	"layer3+4": BOND_XMIT_HASH_POLICY_LAYER3_4, | ||||
| 	"layer2+3": BOND_XMIT_HASH_POLICY_LAYER2_3, | ||||
| 	"encap2+3": BOND_XMIT_HASH_POLICY_ENCAP2_3, | ||||
| 	"encap3+4": BOND_XMIT_HASH_POLICY_ENCAP3_4, | ||||
| } | ||||
|  | ||||
| // BondLacpRate type | ||||
| type BondLacpRate int | ||||
|  | ||||
| func (b BondLacpRate) String() string { | ||||
| 	s, ok := bondLacpRateToString[b] | ||||
| 	if !ok { | ||||
| 		return fmt.Sprintf("LacpRate(%d)", b) | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
|  | ||||
| // StringToBondLacpRate returns bond lacp arte, or uknonw is the s is invalid. | ||||
| func StringToBondLacpRate(s string) BondLacpRate { | ||||
| 	lacp, ok := StringToBondLacpRateMap[s] | ||||
| 	if !ok { | ||||
| 		return BOND_LACP_RATE_UNKNOWN | ||||
| 	} | ||||
| 	return lacp | ||||
| } | ||||
|  | ||||
| // Possible BondLacpRate value | ||||
| const ( | ||||
| 	BOND_LACP_RATE_SLOW BondLacpRate = iota | ||||
| 	BOND_LACP_RATE_FAST | ||||
| 	BOND_LACP_RATE_UNKNOWN | ||||
| ) | ||||
|  | ||||
| var bondLacpRateToString = map[BondLacpRate]string{ | ||||
| 	BOND_LACP_RATE_SLOW: "slow", | ||||
| 	BOND_LACP_RATE_FAST: "fast", | ||||
| } | ||||
| var StringToBondLacpRateMap = map[string]BondLacpRate{ | ||||
| 	"slow": BOND_LACP_RATE_SLOW, | ||||
| 	"fast": BOND_LACP_RATE_FAST, | ||||
| } | ||||
|  | ||||
| // BondAdSelect type | ||||
| type BondAdSelect int | ||||
|  | ||||
| // Possible BondAdSelect value | ||||
| const ( | ||||
| 	BOND_AD_SELECT_STABLE BondAdSelect = iota | ||||
| 	BOND_AD_SELECT_BANDWIDTH | ||||
| 	BOND_AD_SELECT_COUNT | ||||
| ) | ||||
|  | ||||
| // BondAdInfo | ||||
| type BondAdInfo struct { | ||||
| 	AggregatorId int | ||||
| 	NumPorts     int | ||||
| 	ActorKey     int | ||||
| 	PartnerKey   int | ||||
| 	PartnerMac   net.HardwareAddr | ||||
| } | ||||
|  | ||||
| // Bond representation | ||||
| type Bond struct { | ||||
| 	LinkAttrs | ||||
| 	Mode            BondMode | ||||
| 	ActiveSlave     int | ||||
| 	Miimon          int | ||||
| 	UpDelay         int | ||||
| 	DownDelay       int | ||||
| 	UseCarrier      int | ||||
| 	ArpInterval     int | ||||
| 	ArpIpTargets    []net.IP | ||||
| 	ArpValidate     BondArpValidate | ||||
| 	ArpAllTargets   BondArpAllTargets | ||||
| 	Primary         int | ||||
| 	PrimaryReselect BondPrimaryReselect | ||||
| 	FailOverMac     BondFailOverMac | ||||
| 	XmitHashPolicy  BondXmitHashPolicy | ||||
| 	ResendIgmp      int | ||||
| 	NumPeerNotif    int | ||||
| 	AllSlavesActive int | ||||
| 	MinLinks        int | ||||
| 	LpInterval      int | ||||
| 	PackersPerSlave int | ||||
| 	LacpRate        BondLacpRate | ||||
| 	AdSelect        BondAdSelect | ||||
| 	// looking at iproute tool AdInfo can only be retrived. It can't be set. | ||||
| 	AdInfo *BondAdInfo | ||||
| } | ||||
|  | ||||
| func NewLinkBond(atr LinkAttrs) *Bond { | ||||
| 	return &Bond{ | ||||
| 		LinkAttrs:       atr, | ||||
| 		Mode:            -1, | ||||
| 		ActiveSlave:     -1, | ||||
| 		Miimon:          -1, | ||||
| 		UpDelay:         -1, | ||||
| 		DownDelay:       -1, | ||||
| 		UseCarrier:      -1, | ||||
| 		ArpInterval:     -1, | ||||
| 		ArpIpTargets:    nil, | ||||
| 		ArpValidate:     -1, | ||||
| 		ArpAllTargets:   -1, | ||||
| 		Primary:         -1, | ||||
| 		PrimaryReselect: -1, | ||||
| 		FailOverMac:     -1, | ||||
| 		XmitHashPolicy:  -1, | ||||
| 		ResendIgmp:      -1, | ||||
| 		NumPeerNotif:    -1, | ||||
| 		AllSlavesActive: -1, | ||||
| 		MinLinks:        -1, | ||||
| 		LpInterval:      -1, | ||||
| 		PackersPerSlave: -1, | ||||
| 		LacpRate:        -1, | ||||
| 		AdSelect:        -1, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Flag mask for bond options. Bond.Flagmask must be set to on for option to work. | ||||
| const ( | ||||
| 	BOND_MODE_MASK uint64 = 1 << (1 + iota) | ||||
| 	BOND_ACTIVE_SLAVE_MASK | ||||
| 	BOND_MIIMON_MASK | ||||
| 	BOND_UPDELAY_MASK | ||||
| 	BOND_DOWNDELAY_MASK | ||||
| 	BOND_USE_CARRIER_MASK | ||||
| 	BOND_ARP_INTERVAL_MASK | ||||
| 	BOND_ARP_VALIDATE_MASK | ||||
| 	BOND_ARP_ALL_TARGETS_MASK | ||||
| 	BOND_PRIMARY_MASK | ||||
| 	BOND_PRIMARY_RESELECT_MASK | ||||
| 	BOND_FAIL_OVER_MAC_MASK | ||||
| 	BOND_XMIT_HASH_POLICY_MASK | ||||
| 	BOND_RESEND_IGMP_MASK | ||||
| 	BOND_NUM_PEER_NOTIF_MASK | ||||
| 	BOND_ALL_SLAVES_ACTIVE_MASK | ||||
| 	BOND_MIN_LINKS_MASK | ||||
| 	BOND_LP_INTERVAL_MASK | ||||
| 	BOND_PACKETS_PER_SLAVE_MASK | ||||
| 	BOND_LACP_RATE_MASK | ||||
| 	BOND_AD_SELECT_MASK | ||||
| ) | ||||
|  | ||||
| // Attrs implementation. | ||||
| func (bond *Bond) Attrs() *LinkAttrs { | ||||
| 	return &bond.LinkAttrs | ||||
| } | ||||
|  | ||||
| // Type implementation fro Vxlan. | ||||
| func (bond *Bond) Type() string { | ||||
| 	return "bond" | ||||
| } | ||||
|  | ||||
| // GreTap devices must specify LocalIP and RemoteIP on create | ||||
| type Gretap struct { | ||||
| 	LinkAttrs | ||||
| 	IKey       uint32 | ||||
| 	OKey       uint32 | ||||
| 	EncapSport uint16 | ||||
| 	EncapDport uint16 | ||||
| 	Local      net.IP | ||||
| 	Remote     net.IP | ||||
| 	IFlags     uint16 | ||||
| 	OFlags     uint16 | ||||
| 	PMtuDisc   uint8 | ||||
| 	Ttl        uint8 | ||||
| 	Tos        uint8 | ||||
| 	EncapType  uint16 | ||||
| 	EncapFlags uint16 | ||||
| 	Link       uint32 | ||||
| } | ||||
|  | ||||
| func (gretap *Gretap) Attrs() *LinkAttrs { | ||||
| 	return &gretap.LinkAttrs | ||||
| } | ||||
|  | ||||
| func (gretap *Gretap) Type() string { | ||||
| 	return "gretap" | ||||
| } | ||||
|  | ||||
| // iproute2 supported devices; | ||||
| // vlan | veth | vcan | dummy | ifb | macvlan | macvtap | | ||||
| // bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan | | ||||
| // gre | gretap | ip6gre | ip6gretap | vti | nlmon | | ||||
| // bond_slave | ipvlan | ||||
							
								
								
									
										1160
									
								
								vendor/github.com/vishvananda/netlink/link_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1160
									
								
								vendor/github.com/vishvananda/netlink/link_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										14
									
								
								vendor/github.com/vishvananda/netlink/link_tuntap_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/vishvananda/netlink/link_tuntap_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,14 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| // ideally golang.org/x/sys/unix would define IfReq but it only has | ||||
| // IFNAMSIZ, hence this minimalistic implementation | ||||
| const ( | ||||
| 	SizeOfIfReq = 40 | ||||
| 	IFNAMSIZ    = 16 | ||||
| ) | ||||
|  | ||||
| type ifReq struct { | ||||
| 	Name  [IFNAMSIZ]byte | ||||
| 	Flags uint16 | ||||
| 	pad   [SizeOfIfReq - IFNAMSIZ - 2]byte | ||||
| } | ||||
							
								
								
									
										22
									
								
								vendor/github.com/vishvananda/netlink/neigh.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/vishvananda/netlink/neigh.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,22 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| ) | ||||
|  | ||||
| // Neigh represents a link layer neighbor from netlink. | ||||
| type Neigh struct { | ||||
| 	LinkIndex    int | ||||
| 	Family       int | ||||
| 	State        int | ||||
| 	Type         int | ||||
| 	Flags        int | ||||
| 	IP           net.IP | ||||
| 	HardwareAddr net.HardwareAddr | ||||
| } | ||||
|  | ||||
| // String returns $ip/$hwaddr $label | ||||
| func (neigh *Neigh) String() string { | ||||
| 	return fmt.Sprintf("%s %s", neigh.IP, neigh.HardwareAddr) | ||||
| } | ||||
							
								
								
									
										190
									
								
								vendor/github.com/vishvananda/netlink/neigh_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										190
									
								
								vendor/github.com/vishvananda/netlink/neigh_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,190 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"net" | ||||
| 	"syscall" | ||||
| 	"unsafe" | ||||
|  | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	NDA_UNSPEC = iota | ||||
| 	NDA_DST | ||||
| 	NDA_LLADDR | ||||
| 	NDA_CACHEINFO | ||||
| 	NDA_PROBES | ||||
| 	NDA_VLAN | ||||
| 	NDA_PORT | ||||
| 	NDA_VNI | ||||
| 	NDA_IFINDEX | ||||
| 	NDA_MAX = NDA_IFINDEX | ||||
| ) | ||||
|  | ||||
| // Neighbor Cache Entry States. | ||||
| const ( | ||||
| 	NUD_NONE       = 0x00 | ||||
| 	NUD_INCOMPLETE = 0x01 | ||||
| 	NUD_REACHABLE  = 0x02 | ||||
| 	NUD_STALE      = 0x04 | ||||
| 	NUD_DELAY      = 0x08 | ||||
| 	NUD_PROBE      = 0x10 | ||||
| 	NUD_FAILED     = 0x20 | ||||
| 	NUD_NOARP      = 0x40 | ||||
| 	NUD_PERMANENT  = 0x80 | ||||
| ) | ||||
|  | ||||
| // Neighbor Flags | ||||
| const ( | ||||
| 	NTF_USE    = 0x01 | ||||
| 	NTF_SELF   = 0x02 | ||||
| 	NTF_MASTER = 0x04 | ||||
| 	NTF_PROXY  = 0x08 | ||||
| 	NTF_ROUTER = 0x80 | ||||
| ) | ||||
|  | ||||
| type Ndmsg struct { | ||||
| 	Family uint8 | ||||
| 	Index  uint32 | ||||
| 	State  uint16 | ||||
| 	Flags  uint8 | ||||
| 	Type   uint8 | ||||
| } | ||||
|  | ||||
| func deserializeNdmsg(b []byte) *Ndmsg { | ||||
| 	var dummy Ndmsg | ||||
| 	return (*Ndmsg)(unsafe.Pointer(&b[0:unsafe.Sizeof(dummy)][0])) | ||||
| } | ||||
|  | ||||
| func (msg *Ndmsg) Serialize() []byte { | ||||
| 	return (*(*[unsafe.Sizeof(*msg)]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
|  | ||||
| func (msg *Ndmsg) Len() int { | ||||
| 	return int(unsafe.Sizeof(*msg)) | ||||
| } | ||||
|  | ||||
| // NeighAdd will add an IP to MAC mapping to the ARP table | ||||
| // Equivalent to: `ip neigh add ....` | ||||
| func NeighAdd(neigh *Neigh) error { | ||||
| 	return neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL) | ||||
| } | ||||
|  | ||||
| // NeighSet will add or replace an IP to MAC mapping to the ARP table | ||||
| // Equivalent to: `ip neigh replace....` | ||||
| func NeighSet(neigh *Neigh) error { | ||||
| 	return neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_REPLACE) | ||||
| } | ||||
|  | ||||
| // NeighAppend will append an entry to FDB | ||||
| // Equivalent to: `bridge fdb append...` | ||||
| func NeighAppend(neigh *Neigh) error { | ||||
| 	return neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_APPEND) | ||||
| } | ||||
|  | ||||
| func neighAdd(neigh *Neigh, mode int) error { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_NEWNEIGH, mode|syscall.NLM_F_ACK) | ||||
| 	return neighHandle(neigh, req) | ||||
| } | ||||
|  | ||||
| // NeighDel will delete an IP address from a link device. | ||||
| // Equivalent to: `ip addr del $addr dev $link` | ||||
| func NeighDel(neigh *Neigh) error { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_DELNEIGH, syscall.NLM_F_ACK) | ||||
| 	return neighHandle(neigh, req) | ||||
| } | ||||
|  | ||||
| func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error { | ||||
| 	var family int | ||||
| 	if neigh.Family > 0 { | ||||
| 		family = neigh.Family | ||||
| 	} else { | ||||
| 		family = nl.GetIPFamily(neigh.IP) | ||||
| 	} | ||||
|  | ||||
| 	msg := Ndmsg{ | ||||
| 		Family: uint8(family), | ||||
| 		Index:  uint32(neigh.LinkIndex), | ||||
| 		State:  uint16(neigh.State), | ||||
| 		Type:   uint8(neigh.Type), | ||||
| 		Flags:  uint8(neigh.Flags), | ||||
| 	} | ||||
| 	req.AddData(&msg) | ||||
|  | ||||
| 	ipData := neigh.IP.To4() | ||||
| 	if ipData == nil { | ||||
| 		ipData = neigh.IP.To16() | ||||
| 	} | ||||
|  | ||||
| 	dstData := nl.NewRtAttr(NDA_DST, ipData) | ||||
| 	req.AddData(dstData) | ||||
|  | ||||
| 	hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr)) | ||||
| 	req.AddData(hwData) | ||||
|  | ||||
| 	_, err := req.Execute(syscall.NETLINK_ROUTE, 0) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // NeighList gets a list of IP-MAC mappings in the system (ARP table). | ||||
| // Equivalent to: `ip neighbor show`. | ||||
| // The list can be filtered by link and ip family. | ||||
| func NeighList(linkIndex, family int) ([]Neigh, error) { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_GETNEIGH, syscall.NLM_F_DUMP) | ||||
| 	msg := Ndmsg{ | ||||
| 		Family: uint8(family), | ||||
| 		Index:  uint32(linkIndex), | ||||
| 	} | ||||
| 	req.AddData(&msg) | ||||
|  | ||||
| 	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWNEIGH) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var res []Neigh | ||||
| 	for _, m := range msgs { | ||||
| 		ndm := deserializeNdmsg(m) | ||||
| 		if linkIndex != 0 && int(ndm.Index) != linkIndex { | ||||
| 			// Ignore messages from other interfaces | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		neigh, err := NeighDeserialize(m) | ||||
| 		if err != nil { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		res = append(res, *neigh) | ||||
| 	} | ||||
|  | ||||
| 	return res, nil | ||||
| } | ||||
|  | ||||
| func NeighDeserialize(m []byte) (*Neigh, error) { | ||||
| 	msg := deserializeNdmsg(m) | ||||
|  | ||||
| 	neigh := Neigh{ | ||||
| 		LinkIndex: int(msg.Index), | ||||
| 		Family:    int(msg.Family), | ||||
| 		State:     int(msg.State), | ||||
| 		Type:      int(msg.Type), | ||||
| 		Flags:     int(msg.Flags), | ||||
| 	} | ||||
|  | ||||
| 	attrs, err := nl.ParseRouteAttr(m[msg.Len():]) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	for _, attr := range attrs { | ||||
| 		switch attr.Attr.Type { | ||||
| 		case NDA_DST: | ||||
| 			neigh.IP = net.IP(attr.Value) | ||||
| 		case NDA_LLADDR: | ||||
| 			neigh.HardwareAddr = net.HardwareAddr(attr.Value) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return &neigh, nil | ||||
| } | ||||
							
								
								
									
										42
									
								
								vendor/github.com/vishvananda/netlink/netlink.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								vendor/github.com/vishvananda/netlink/netlink.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,42 +0,0 @@ | ||||
| // Package netlink provides a simple library for netlink. Netlink is | ||||
| // the interface a user-space program in linux uses to communicate with | ||||
| // the kernel. It can be used to add and remove interfaces, set up ip | ||||
| // addresses and routes, and confiugre ipsec. Netlink communication | ||||
| // requires elevated privileges, so in most cases this code needs to | ||||
| // be run as root. The low level primitives for netlink are contained | ||||
| // in the nl subpackage. This package attempts to provide a high-level | ||||
| // interface that is loosly modeled on the iproute2 cli. | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"net" | ||||
|  | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// Family type definitions | ||||
| 	FAMILY_ALL = nl.FAMILY_ALL | ||||
| 	FAMILY_V4  = nl.FAMILY_V4 | ||||
| 	FAMILY_V6  = nl.FAMILY_V6 | ||||
| ) | ||||
|  | ||||
| // ParseIPNet parses a string in ip/net format and returns a net.IPNet. | ||||
| // This is valuable because addresses in netlink are often IPNets and | ||||
| // ParseCIDR returns an IPNet with the IP part set to the base IP of the | ||||
| // range. | ||||
| func ParseIPNet(s string) (*net.IPNet, error) { | ||||
| 	ip, ipNet, err := net.ParseCIDR(s) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &net.IPNet{IP: ip, Mask: ipNet.Mask}, nil | ||||
| } | ||||
|  | ||||
| // NewIPNet generates an IPNet from an ip address using a netmask of 32 or 128. | ||||
| func NewIPNet(ip net.IP) *net.IPNet { | ||||
| 	if ip.To4() != nil { | ||||
| 		return &net.IPNet{IP: ip, Mask: net.CIDRMask(32, 32)} | ||||
| 	} | ||||
| 	return &net.IPNet{IP: ip, Mask: net.CIDRMask(128, 128)} | ||||
| } | ||||
							
								
								
									
										143
									
								
								vendor/github.com/vishvananda/netlink/netlink_unspecified.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										143
									
								
								vendor/github.com/vishvananda/netlink/netlink_unspecified.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,143 +0,0 @@ | ||||
| // +build !linux | ||||
|  | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	ErrNotImplemented = errors.New("not implemented") | ||||
| ) | ||||
|  | ||||
| func LinkSetUp(link *Link) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func LinkSetDown(link *Link) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func LinkSetMTU(link *Link, mtu int) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func LinkSetMaster(link *Link, master *Link) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func LinkSetNsPid(link *Link, nspid int) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func LinkSetNsFd(link *Link, fd int) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func LinkAdd(link *Link) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func LinkDel(link *Link) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func SetHairpin(link Link, mode bool) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func SetGuard(link Link, mode bool) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func SetFastLeave(link Link, mode bool) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func SetLearning(link Link, mode bool) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func SetRootBlock(link Link, mode bool) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func SetFlood(link Link, mode bool) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func LinkList() ([]Link, error) { | ||||
| 	return nil, ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func AddrAdd(link *Link, addr *Addr) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func AddrDel(link *Link, addr *Addr) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func AddrList(link *Link, family int) ([]Addr, error) { | ||||
| 	return nil, ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func RouteAdd(route *Route) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func RouteDel(route *Route) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func RouteList(link *Link, family int) ([]Route, error) { | ||||
| 	return nil, ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func XfrmPolicyAdd(policy *XfrmPolicy) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func XfrmPolicyDel(policy *XfrmPolicy) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func XfrmPolicyList(family int) ([]XfrmPolicy, error) { | ||||
| 	return nil, ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func XfrmStateAdd(policy *XfrmState) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func XfrmStateDel(policy *XfrmState) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func XfrmStateList(family int) ([]XfrmState, error) { | ||||
| 	return nil, ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func NeighAdd(neigh *Neigh) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func NeighSet(neigh *Neigh) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func NeighAppend(neigh *Neigh) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func NeighDel(neigh *Neigh) error { | ||||
| 	return ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func NeighList(linkIndex, family int) ([]Neigh, error) { | ||||
| 	return nil, ErrNotImplemented | ||||
| } | ||||
|  | ||||
| func NeighDeserialize(m []byte) (*Ndmsg, *Neigh, error) { | ||||
| 	return nil, nil, ErrNotImplemented | ||||
| } | ||||
							
								
								
									
										47
									
								
								vendor/github.com/vishvananda/netlink/nl/addr_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										47
									
								
								vendor/github.com/vishvananda/netlink/nl/addr_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,47 +0,0 @@ | ||||
| package nl | ||||
|  | ||||
| import ( | ||||
| 	"syscall" | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| type IfAddrmsg struct { | ||||
| 	syscall.IfAddrmsg | ||||
| } | ||||
|  | ||||
| func NewIfAddrmsg(family int) *IfAddrmsg { | ||||
| 	return &IfAddrmsg{ | ||||
| 		IfAddrmsg: syscall.IfAddrmsg{ | ||||
| 			Family: uint8(family), | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // struct ifaddrmsg { | ||||
| //   __u8    ifa_family; | ||||
| //   __u8    ifa_prefixlen;  /* The prefix length    */ | ||||
| //   __u8    ifa_flags;  /* Flags      */ | ||||
| //   __u8    ifa_scope;  /* Address scope    */ | ||||
| //   __u32   ifa_index;  /* Link index     */ | ||||
| // }; | ||||
|  | ||||
| // type IfAddrmsg struct { | ||||
| // 	Family    uint8 | ||||
| // 	Prefixlen uint8 | ||||
| // 	Flags     uint8 | ||||
| // 	Scope     uint8 | ||||
| // 	Index     uint32 | ||||
| // } | ||||
| // SizeofIfAddrmsg     = 0x8 | ||||
|  | ||||
| func DeserializeIfAddrmsg(b []byte) *IfAddrmsg { | ||||
| 	return (*IfAddrmsg)(unsafe.Pointer(&b[0:syscall.SizeofIfAddrmsg][0])) | ||||
| } | ||||
|  | ||||
| func (msg *IfAddrmsg) Serialize() []byte { | ||||
| 	return (*(*[syscall.SizeofIfAddrmsg]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
|  | ||||
| func (msg *IfAddrmsg) Len() int { | ||||
| 	return syscall.SizeofIfAddrmsg | ||||
| } | ||||
							
								
								
									
										184
									
								
								vendor/github.com/vishvananda/netlink/nl/link_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										184
									
								
								vendor/github.com/vishvananda/netlink/nl/link_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,184 +0,0 @@ | ||||
| package nl | ||||
|  | ||||
| const ( | ||||
| 	DEFAULT_CHANGE = 0xFFFFFFFF | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	IFLA_INFO_UNSPEC = iota | ||||
| 	IFLA_INFO_KIND | ||||
| 	IFLA_INFO_DATA | ||||
| 	IFLA_INFO_XSTATS | ||||
| 	IFLA_INFO_MAX = IFLA_INFO_XSTATS | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	IFLA_VLAN_UNSPEC = iota | ||||
| 	IFLA_VLAN_ID | ||||
| 	IFLA_VLAN_FLAGS | ||||
| 	IFLA_VLAN_EGRESS_QOS | ||||
| 	IFLA_VLAN_INGRESS_QOS | ||||
| 	IFLA_VLAN_PROTOCOL | ||||
| 	IFLA_VLAN_MAX = IFLA_VLAN_PROTOCOL | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	VETH_INFO_UNSPEC = iota | ||||
| 	VETH_INFO_PEER | ||||
| 	VETH_INFO_MAX = VETH_INFO_PEER | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	IFLA_VXLAN_UNSPEC = iota | ||||
| 	IFLA_VXLAN_ID | ||||
| 	IFLA_VXLAN_GROUP | ||||
| 	IFLA_VXLAN_LINK | ||||
| 	IFLA_VXLAN_LOCAL | ||||
| 	IFLA_VXLAN_TTL | ||||
| 	IFLA_VXLAN_TOS | ||||
| 	IFLA_VXLAN_LEARNING | ||||
| 	IFLA_VXLAN_AGEING | ||||
| 	IFLA_VXLAN_LIMIT | ||||
| 	IFLA_VXLAN_PORT_RANGE | ||||
| 	IFLA_VXLAN_PROXY | ||||
| 	IFLA_VXLAN_RSC | ||||
| 	IFLA_VXLAN_L2MISS | ||||
| 	IFLA_VXLAN_L3MISS | ||||
| 	IFLA_VXLAN_PORT | ||||
| 	IFLA_VXLAN_GROUP6 | ||||
| 	IFLA_VXLAN_LOCAL6 | ||||
| 	IFLA_VXLAN_UDP_CSUM | ||||
| 	IFLA_VXLAN_UDP_ZERO_CSUM6_TX | ||||
| 	IFLA_VXLAN_UDP_ZERO_CSUM6_RX | ||||
| 	IFLA_VXLAN_REMCSUM_TX | ||||
| 	IFLA_VXLAN_REMCSUM_RX | ||||
| 	IFLA_VXLAN_GBP | ||||
| 	IFLA_VXLAN_REMCSUM_NOPARTIAL | ||||
| 	IFLA_VXLAN_FLOWBASED | ||||
| 	IFLA_VXLAN_MAX = IFLA_VXLAN_FLOWBASED | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	BRIDGE_MODE_UNSPEC = iota | ||||
| 	BRIDGE_MODE_HAIRPIN | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	IFLA_BRPORT_UNSPEC = iota | ||||
| 	IFLA_BRPORT_STATE | ||||
| 	IFLA_BRPORT_PRIORITY | ||||
| 	IFLA_BRPORT_COST | ||||
| 	IFLA_BRPORT_MODE | ||||
| 	IFLA_BRPORT_GUARD | ||||
| 	IFLA_BRPORT_PROTECT | ||||
| 	IFLA_BRPORT_FAST_LEAVE | ||||
| 	IFLA_BRPORT_LEARNING | ||||
| 	IFLA_BRPORT_UNICAST_FLOOD | ||||
| 	IFLA_BRPORT_MAX = IFLA_BRPORT_UNICAST_FLOOD | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	IFLA_IPVLAN_UNSPEC = iota | ||||
| 	IFLA_IPVLAN_MODE | ||||
| 	IFLA_IPVLAN_MAX = IFLA_IPVLAN_MODE | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// not defined in syscall | ||||
| 	IFLA_NET_NS_FD = 28 | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	IFLA_MACVLAN_UNSPEC = iota | ||||
| 	IFLA_MACVLAN_MODE | ||||
| 	IFLA_MACVLAN_FLAGS | ||||
| 	IFLA_MACVLAN_MAX = IFLA_MACVLAN_FLAGS | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	MACVLAN_MODE_PRIVATE  = 1 | ||||
| 	MACVLAN_MODE_VEPA     = 2 | ||||
| 	MACVLAN_MODE_BRIDGE   = 4 | ||||
| 	MACVLAN_MODE_PASSTHRU = 8 | ||||
| 	MACVLAN_MODE_SOURCE   = 16 | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	IFLA_BOND_UNSPEC = iota | ||||
| 	IFLA_BOND_MODE | ||||
| 	IFLA_BOND_ACTIVE_SLAVE | ||||
| 	IFLA_BOND_MIIMON | ||||
| 	IFLA_BOND_UPDELAY | ||||
| 	IFLA_BOND_DOWNDELAY | ||||
| 	IFLA_BOND_USE_CARRIER | ||||
| 	IFLA_BOND_ARP_INTERVAL | ||||
| 	IFLA_BOND_ARP_IP_TARGET | ||||
| 	IFLA_BOND_ARP_VALIDATE | ||||
| 	IFLA_BOND_ARP_ALL_TARGETS | ||||
| 	IFLA_BOND_PRIMARY | ||||
| 	IFLA_BOND_PRIMARY_RESELECT | ||||
| 	IFLA_BOND_FAIL_OVER_MAC | ||||
| 	IFLA_BOND_XMIT_HASH_POLICY | ||||
| 	IFLA_BOND_RESEND_IGMP | ||||
| 	IFLA_BOND_NUM_PEER_NOTIF | ||||
| 	IFLA_BOND_ALL_SLAVES_ACTIVE | ||||
| 	IFLA_BOND_MIN_LINKS | ||||
| 	IFLA_BOND_LP_INTERVAL | ||||
| 	IFLA_BOND_PACKETS_PER_SLAVE | ||||
| 	IFLA_BOND_AD_LACP_RATE | ||||
| 	IFLA_BOND_AD_SELECT | ||||
| 	IFLA_BOND_AD_INFO | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	IFLA_BOND_AD_INFO_UNSPEC = iota | ||||
| 	IFLA_BOND_AD_INFO_AGGREGATOR | ||||
| 	IFLA_BOND_AD_INFO_NUM_PORTS | ||||
| 	IFLA_BOND_AD_INFO_ACTOR_KEY | ||||
| 	IFLA_BOND_AD_INFO_PARTNER_KEY | ||||
| 	IFLA_BOND_AD_INFO_PARTNER_MAC | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	IFLA_BOND_SLAVE_UNSPEC = iota | ||||
| 	IFLA_BOND_SLAVE_STATE | ||||
| 	IFLA_BOND_SLAVE_MII_STATUS | ||||
| 	IFLA_BOND_SLAVE_LINK_FAILURE_COUNT | ||||
| 	IFLA_BOND_SLAVE_PERM_HWADDR | ||||
| 	IFLA_BOND_SLAVE_QUEUE_ID | ||||
| 	IFLA_BOND_SLAVE_AD_AGGREGATOR_ID | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	IFLA_GRE_UNSPEC = iota | ||||
| 	IFLA_GRE_LINK | ||||
| 	IFLA_GRE_IFLAGS | ||||
| 	IFLA_GRE_OFLAGS | ||||
| 	IFLA_GRE_IKEY | ||||
| 	IFLA_GRE_OKEY | ||||
| 	IFLA_GRE_LOCAL | ||||
| 	IFLA_GRE_REMOTE | ||||
| 	IFLA_GRE_TTL | ||||
| 	IFLA_GRE_TOS | ||||
| 	IFLA_GRE_PMTUDISC | ||||
| 	IFLA_GRE_ENCAP_LIMIT | ||||
| 	IFLA_GRE_FLOWINFO | ||||
| 	IFLA_GRE_FLAGS | ||||
| 	IFLA_GRE_ENCAP_TYPE | ||||
| 	IFLA_GRE_ENCAP_FLAGS | ||||
| 	IFLA_GRE_ENCAP_SPORT | ||||
| 	IFLA_GRE_ENCAP_DPORT | ||||
| 	IFLA_GRE_COLLECT_METADATA | ||||
| 	IFLA_GRE_MAX = IFLA_GRE_COLLECT_METADATA | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	GRE_CSUM    = 0x8000 | ||||
| 	GRE_ROUTING = 0x4000 | ||||
| 	GRE_KEY     = 0x2000 | ||||
| 	GRE_SEQ     = 0x1000 | ||||
| 	GRE_STRICT  = 0x0800 | ||||
| 	GRE_REC     = 0x0700 | ||||
| 	GRE_FLAGS   = 0x00F8 | ||||
| 	GRE_VERSION = 0x0007 | ||||
| ) | ||||
							
								
								
									
										424
									
								
								vendor/github.com/vishvananda/netlink/nl/nl_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										424
									
								
								vendor/github.com/vishvananda/netlink/nl/nl_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,424 +0,0 @@ | ||||
| // Package nl has low level primitives for making Netlink calls. | ||||
| package nl | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"sync/atomic" | ||||
| 	"syscall" | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// Family type definitions | ||||
| 	FAMILY_ALL = syscall.AF_UNSPEC | ||||
| 	FAMILY_V4  = syscall.AF_INET | ||||
| 	FAMILY_V6  = syscall.AF_INET6 | ||||
| ) | ||||
|  | ||||
| var nextSeqNr uint32 | ||||
|  | ||||
| // GetIPFamily returns the family type of a net.IP. | ||||
| func GetIPFamily(ip net.IP) int { | ||||
| 	if len(ip) <= net.IPv4len { | ||||
| 		return FAMILY_V4 | ||||
| 	} | ||||
| 	if ip.To4() != nil { | ||||
| 		return FAMILY_V4 | ||||
| 	} | ||||
| 	return FAMILY_V6 | ||||
| } | ||||
|  | ||||
| var nativeEndian binary.ByteOrder | ||||
|  | ||||
| // Get native endianness for the system | ||||
| func NativeEndian() binary.ByteOrder { | ||||
| 	if nativeEndian == nil { | ||||
| 		var x uint32 = 0x01020304 | ||||
| 		if *(*byte)(unsafe.Pointer(&x)) == 0x01 { | ||||
| 			nativeEndian = binary.BigEndian | ||||
| 		} else { | ||||
| 			nativeEndian = binary.LittleEndian | ||||
| 		} | ||||
| 	} | ||||
| 	return nativeEndian | ||||
| } | ||||
|  | ||||
| // Byte swap a 16 bit value if we aren't big endian | ||||
| func Swap16(i uint16) uint16 { | ||||
| 	if NativeEndian() == binary.BigEndian { | ||||
| 		return i | ||||
| 	} | ||||
| 	return (i&0xff00)>>8 | (i&0xff)<<8 | ||||
| } | ||||
|  | ||||
| // Byte swap a 32 bit value if aren't big endian | ||||
| func Swap32(i uint32) uint32 { | ||||
| 	if NativeEndian() == binary.BigEndian { | ||||
| 		return i | ||||
| 	} | ||||
| 	return (i&0xff000000)>>24 | (i&0xff0000)>>8 | (i&0xff00)<<8 | (i&0xff)<<24 | ||||
| } | ||||
|  | ||||
| type NetlinkRequestData interface { | ||||
| 	Len() int | ||||
| 	Serialize() []byte | ||||
| } | ||||
|  | ||||
| // IfInfomsg is related to links, but it is used for list requests as well | ||||
| type IfInfomsg struct { | ||||
| 	syscall.IfInfomsg | ||||
| } | ||||
|  | ||||
| // Create an IfInfomsg with family specified | ||||
| func NewIfInfomsg(family int) *IfInfomsg { | ||||
| 	return &IfInfomsg{ | ||||
| 		IfInfomsg: syscall.IfInfomsg{ | ||||
| 			Family: uint8(family), | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func DeserializeIfInfomsg(b []byte) *IfInfomsg { | ||||
| 	return (*IfInfomsg)(unsafe.Pointer(&b[0:syscall.SizeofIfInfomsg][0])) | ||||
| } | ||||
|  | ||||
| func (msg *IfInfomsg) Serialize() []byte { | ||||
| 	return (*(*[syscall.SizeofIfInfomsg]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
|  | ||||
| func (msg *IfInfomsg) Len() int { | ||||
| 	return syscall.SizeofIfInfomsg | ||||
| } | ||||
|  | ||||
| func rtaAlignOf(attrlen int) int { | ||||
| 	return (attrlen + syscall.RTA_ALIGNTO - 1) & ^(syscall.RTA_ALIGNTO - 1) | ||||
| } | ||||
|  | ||||
| func NewIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg { | ||||
| 	msg := NewIfInfomsg(family) | ||||
| 	parent.children = append(parent.children, msg) | ||||
| 	return msg | ||||
| } | ||||
|  | ||||
| // Extend RtAttr to handle data and children | ||||
| type RtAttr struct { | ||||
| 	syscall.RtAttr | ||||
| 	Data     []byte | ||||
| 	children []NetlinkRequestData | ||||
| } | ||||
|  | ||||
| // Create a new Extended RtAttr object | ||||
| func NewRtAttr(attrType int, data []byte) *RtAttr { | ||||
| 	return &RtAttr{ | ||||
| 		RtAttr: syscall.RtAttr{ | ||||
| 			Type: uint16(attrType), | ||||
| 		}, | ||||
| 		children: []NetlinkRequestData{}, | ||||
| 		Data:     data, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Create a new RtAttr obj anc add it as a child of an existing object | ||||
| func NewRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr { | ||||
| 	attr := NewRtAttr(attrType, data) | ||||
| 	parent.children = append(parent.children, attr) | ||||
| 	return attr | ||||
| } | ||||
|  | ||||
| func (a *RtAttr) Len() int { | ||||
| 	if len(a.children) == 0 { | ||||
| 		return (syscall.SizeofRtAttr + len(a.Data)) | ||||
| 	} | ||||
|  | ||||
| 	l := 0 | ||||
| 	for _, child := range a.children { | ||||
| 		l += rtaAlignOf(child.Len()) | ||||
| 	} | ||||
| 	l += syscall.SizeofRtAttr | ||||
| 	return rtaAlignOf(l + len(a.Data)) | ||||
| } | ||||
|  | ||||
| // Serialize the RtAttr into a byte array | ||||
| // This can't just unsafe.cast because it must iterate through children. | ||||
| func (a *RtAttr) Serialize() []byte { | ||||
| 	native := NativeEndian() | ||||
|  | ||||
| 	length := a.Len() | ||||
| 	buf := make([]byte, rtaAlignOf(length)) | ||||
|  | ||||
| 	next := 4 | ||||
| 	if a.Data != nil { | ||||
| 		copy(buf[next:], a.Data) | ||||
| 		next += rtaAlignOf(len(a.Data)) | ||||
| 	} | ||||
| 	if len(a.children) > 0 { | ||||
| 		for _, child := range a.children { | ||||
| 			childBuf := child.Serialize() | ||||
| 			copy(buf[next:], childBuf) | ||||
| 			next += rtaAlignOf(len(childBuf)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if l := uint16(length); l != 0 { | ||||
| 		native.PutUint16(buf[0:2], l) | ||||
| 	} | ||||
| 	native.PutUint16(buf[2:4], a.Type) | ||||
| 	return buf | ||||
| } | ||||
|  | ||||
| type NetlinkRequest struct { | ||||
| 	syscall.NlMsghdr | ||||
| 	Data []NetlinkRequestData | ||||
| } | ||||
|  | ||||
| // Serialize the Netlink Request into a byte array | ||||
| func (req *NetlinkRequest) Serialize() []byte { | ||||
| 	length := syscall.SizeofNlMsghdr | ||||
| 	dataBytes := make([][]byte, len(req.Data)) | ||||
| 	for i, data := range req.Data { | ||||
| 		dataBytes[i] = data.Serialize() | ||||
| 		length = length + len(dataBytes[i]) | ||||
| 	} | ||||
| 	req.Len = uint32(length) | ||||
| 	b := make([]byte, length) | ||||
| 	hdr := (*(*[syscall.SizeofNlMsghdr]byte)(unsafe.Pointer(req)))[:] | ||||
| 	next := syscall.SizeofNlMsghdr | ||||
| 	copy(b[0:next], hdr) | ||||
| 	for _, data := range dataBytes { | ||||
| 		for _, dataByte := range data { | ||||
| 			b[next] = dataByte | ||||
| 			next = next + 1 | ||||
| 		} | ||||
| 	} | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| func (req *NetlinkRequest) AddData(data NetlinkRequestData) { | ||||
| 	if data != nil { | ||||
| 		req.Data = append(req.Data, data) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Execute the request against a the given sockType. | ||||
| // Returns a list of netlink messages in seriaized format, optionally filtered | ||||
| // by resType. | ||||
| func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, error) { | ||||
| 	s, err := getNetlinkSocket(sockType) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer s.Close() | ||||
|  | ||||
| 	if err := s.Send(req); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	pid, err := s.GetPid() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var res [][]byte | ||||
|  | ||||
| done: | ||||
| 	for { | ||||
| 		msgs, err := s.Receive() | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		for _, m := range msgs { | ||||
| 			if m.Header.Seq != req.Seq { | ||||
| 				return nil, fmt.Errorf("Wrong Seq nr %d, expected 1", m.Header.Seq) | ||||
| 			} | ||||
| 			if m.Header.Pid != pid { | ||||
| 				return nil, fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, pid) | ||||
| 			} | ||||
| 			if m.Header.Type == syscall.NLMSG_DONE { | ||||
| 				break done | ||||
| 			} | ||||
| 			if m.Header.Type == syscall.NLMSG_ERROR { | ||||
| 				native := NativeEndian() | ||||
| 				error := int32(native.Uint32(m.Data[0:4])) | ||||
| 				if error == 0 { | ||||
| 					break done | ||||
| 				} | ||||
| 				return nil, syscall.Errno(-error) | ||||
| 			} | ||||
| 			if resType != 0 && m.Header.Type != resType { | ||||
| 				continue | ||||
| 			} | ||||
| 			res = append(res, m.Data) | ||||
| 			if m.Header.Flags&syscall.NLM_F_MULTI == 0 { | ||||
| 				break done | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return res, nil | ||||
| } | ||||
|  | ||||
| // Create a new netlink request from proto and flags | ||||
| // Note the Len value will be inaccurate once data is added until | ||||
| // the message is serialized | ||||
| func NewNetlinkRequest(proto, flags int) *NetlinkRequest { | ||||
| 	return &NetlinkRequest{ | ||||
| 		NlMsghdr: syscall.NlMsghdr{ | ||||
| 			Len:   uint32(syscall.SizeofNlMsghdr), | ||||
| 			Type:  uint16(proto), | ||||
| 			Flags: syscall.NLM_F_REQUEST | uint16(flags), | ||||
| 			Seq:   atomic.AddUint32(&nextSeqNr, 1), | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type NetlinkSocket struct { | ||||
| 	fd  int | ||||
| 	lsa syscall.SockaddrNetlink | ||||
| } | ||||
|  | ||||
| func getNetlinkSocket(protocol int) (*NetlinkSocket, error) { | ||||
| 	fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, protocol) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	s := &NetlinkSocket{ | ||||
| 		fd: fd, | ||||
| 	} | ||||
| 	s.lsa.Family = syscall.AF_NETLINK | ||||
| 	if err := syscall.Bind(fd, &s.lsa); err != nil { | ||||
| 		syscall.Close(fd) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return s, nil | ||||
| } | ||||
|  | ||||
| // Create a netlink socket with a given protocol (e.g. NETLINK_ROUTE) | ||||
| // and subscribe it to multicast groups passed in variable argument list. | ||||
| // Returns the netlink socket on which Receive() method can be called | ||||
| // to retrieve the messages from the kernel. | ||||
| func Subscribe(protocol int, groups ...uint) (*NetlinkSocket, error) { | ||||
| 	fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, protocol) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	s := &NetlinkSocket{ | ||||
| 		fd: fd, | ||||
| 	} | ||||
| 	s.lsa.Family = syscall.AF_NETLINK | ||||
|  | ||||
| 	for _, g := range groups { | ||||
| 		s.lsa.Groups |= (1 << (g - 1)) | ||||
| 	} | ||||
|  | ||||
| 	if err := syscall.Bind(fd, &s.lsa); err != nil { | ||||
| 		syscall.Close(fd) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return s, nil | ||||
| } | ||||
|  | ||||
| func (s *NetlinkSocket) Close() { | ||||
| 	syscall.Close(s.fd) | ||||
| } | ||||
|  | ||||
| func (s *NetlinkSocket) GetFd() int { | ||||
| 	return s.fd | ||||
| } | ||||
|  | ||||
| func (s *NetlinkSocket) Send(request *NetlinkRequest) error { | ||||
| 	if err := syscall.Sendto(s.fd, request.Serialize(), 0, &s.lsa); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) { | ||||
| 	rb := make([]byte, syscall.Getpagesize()) | ||||
| 	nr, _, err := syscall.Recvfrom(s.fd, rb, 0) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if nr < syscall.NLMSG_HDRLEN { | ||||
| 		return nil, fmt.Errorf("Got short response from netlink") | ||||
| 	} | ||||
| 	rb = rb[:nr] | ||||
| 	return syscall.ParseNetlinkMessage(rb) | ||||
| } | ||||
|  | ||||
| func (s *NetlinkSocket) GetPid() (uint32, error) { | ||||
| 	lsa, err := syscall.Getsockname(s.fd) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	switch v := lsa.(type) { | ||||
| 	case *syscall.SockaddrNetlink: | ||||
| 		return v.Pid, nil | ||||
| 	} | ||||
| 	return 0, fmt.Errorf("Wrong socket type") | ||||
| } | ||||
|  | ||||
| func ZeroTerminated(s string) []byte { | ||||
| 	bytes := make([]byte, len(s)+1) | ||||
| 	for i := 0; i < len(s); i++ { | ||||
| 		bytes[i] = s[i] | ||||
| 	} | ||||
| 	bytes[len(s)] = 0 | ||||
| 	return bytes | ||||
| } | ||||
|  | ||||
| func NonZeroTerminated(s string) []byte { | ||||
| 	bytes := make([]byte, len(s)) | ||||
| 	for i := 0; i < len(s); i++ { | ||||
| 		bytes[i] = s[i] | ||||
| 	} | ||||
| 	return bytes | ||||
| } | ||||
|  | ||||
| func BytesToString(b []byte) string { | ||||
| 	n := bytes.Index(b, []byte{0}) | ||||
| 	return string(b[:n]) | ||||
| } | ||||
|  | ||||
| func Uint8Attr(v uint8) []byte { | ||||
| 	return []byte{byte(v)} | ||||
| } | ||||
|  | ||||
| func Uint16Attr(v uint16) []byte { | ||||
| 	native := NativeEndian() | ||||
| 	bytes := make([]byte, 2) | ||||
| 	native.PutUint16(bytes, v) | ||||
| 	return bytes | ||||
| } | ||||
|  | ||||
| func Uint32Attr(v uint32) []byte { | ||||
| 	native := NativeEndian() | ||||
| 	bytes := make([]byte, 4) | ||||
| 	native.PutUint32(bytes, v) | ||||
| 	return bytes | ||||
| } | ||||
|  | ||||
| func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) { | ||||
| 	var attrs []syscall.NetlinkRouteAttr | ||||
| 	for len(b) >= syscall.SizeofRtAttr { | ||||
| 		a, vbuf, alen, err := netlinkRouteAttrAndValue(b) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		ra := syscall.NetlinkRouteAttr{Attr: *a, Value: vbuf[:int(a.Len)-syscall.SizeofRtAttr]} | ||||
| 		attrs = append(attrs, ra) | ||||
| 		b = b[alen:] | ||||
| 	} | ||||
| 	return attrs, nil | ||||
| } | ||||
|  | ||||
| func netlinkRouteAttrAndValue(b []byte) (*syscall.RtAttr, []byte, int, error) { | ||||
| 	a := (*syscall.RtAttr)(unsafe.Pointer(&b[0])) | ||||
| 	if int(a.Len) < syscall.SizeofRtAttr || int(a.Len) > len(b) { | ||||
| 		return nil, nil, 0, syscall.EINVAL | ||||
| 	} | ||||
| 	return a, b[syscall.SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil | ||||
| } | ||||
							
								
								
									
										42
									
								
								vendor/github.com/vishvananda/netlink/nl/route_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								vendor/github.com/vishvananda/netlink/nl/route_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,42 +0,0 @@ | ||||
| package nl | ||||
|  | ||||
| import ( | ||||
| 	"syscall" | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| type RtMsg struct { | ||||
| 	syscall.RtMsg | ||||
| } | ||||
|  | ||||
| func NewRtMsg() *RtMsg { | ||||
| 	return &RtMsg{ | ||||
| 		RtMsg: syscall.RtMsg{ | ||||
| 			Table:    syscall.RT_TABLE_MAIN, | ||||
| 			Scope:    syscall.RT_SCOPE_UNIVERSE, | ||||
| 			Protocol: syscall.RTPROT_BOOT, | ||||
| 			Type:     syscall.RTN_UNICAST, | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func NewRtDelMsg() *RtMsg { | ||||
| 	return &RtMsg{ | ||||
| 		RtMsg: syscall.RtMsg{ | ||||
| 			Table: syscall.RT_TABLE_MAIN, | ||||
| 			Scope: syscall.RT_SCOPE_NOWHERE, | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (msg *RtMsg) Len() int { | ||||
| 	return syscall.SizeofRtMsg | ||||
| } | ||||
|  | ||||
| func DeserializeRtMsg(b []byte) *RtMsg { | ||||
| 	return (*RtMsg)(unsafe.Pointer(&b[0:syscall.SizeofRtMsg][0])) | ||||
| } | ||||
|  | ||||
| func (msg *RtMsg) Serialize() []byte { | ||||
| 	return (*(*[syscall.SizeofRtMsg]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
							
								
								
									
										37
									
								
								vendor/github.com/vishvananda/netlink/nl/syscall.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/vishvananda/netlink/nl/syscall.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,37 +0,0 @@ | ||||
| package nl | ||||
|  | ||||
| // syscall package lack of rule atributes type. | ||||
| // Thus there are defined below | ||||
| const ( | ||||
| 	FRA_UNSPEC  = iota | ||||
| 	FRA_DST     /* destination address */ | ||||
| 	FRA_SRC     /* source address */ | ||||
| 	FRA_IIFNAME /* interface name */ | ||||
| 	FRA_GOTO    /* target to jump to (FR_ACT_GOTO) */ | ||||
| 	FRA_UNUSED2 | ||||
| 	FRA_PRIORITY /* priority/preference */ | ||||
| 	FRA_UNUSED3 | ||||
| 	FRA_UNUSED4 | ||||
| 	FRA_UNUSED5 | ||||
| 	FRA_FWMARK /* mark */ | ||||
| 	FRA_FLOW   /* flow/class id */ | ||||
| 	FRA_TUN_ID | ||||
| 	FRA_SUPPRESS_IFGROUP | ||||
| 	FRA_SUPPRESS_PREFIXLEN | ||||
| 	FRA_TABLE  /* Extended table id */ | ||||
| 	FRA_FWMASK /* mask for netfilter mark */ | ||||
| 	FRA_OIFNAME | ||||
| ) | ||||
|  | ||||
| // ip rule netlink request types | ||||
| const ( | ||||
| 	FR_ACT_UNSPEC = iota | ||||
| 	FR_ACT_TO_TBL /* Pass to fixed table */ | ||||
| 	FR_ACT_GOTO   /* Jump to another rule */ | ||||
| 	FR_ACT_NOP    /* No operation */ | ||||
| 	FR_ACT_RES3 | ||||
| 	FR_ACT_RES4 | ||||
| 	FR_ACT_BLACKHOLE   /* Drop without notification */ | ||||
| 	FR_ACT_UNREACHABLE /* Drop with ENETUNREACH */ | ||||
| 	FR_ACT_PROHIBIT    /* Drop with EACCES */ | ||||
| ) | ||||
							
								
								
									
										627
									
								
								vendor/github.com/vishvananda/netlink/nl/tc_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										627
									
								
								vendor/github.com/vishvananda/netlink/nl/tc_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,627 +0,0 @@ | ||||
| package nl | ||||
|  | ||||
| import ( | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| // LinkLayer | ||||
| const ( | ||||
| 	LINKLAYER_UNSPEC = iota | ||||
| 	LINKLAYER_ETHERNET | ||||
| 	LINKLAYER_ATM | ||||
| ) | ||||
|  | ||||
| // ATM | ||||
| const ( | ||||
| 	ATM_CELL_PAYLOAD = 48 | ||||
| 	ATM_CELL_SIZE    = 53 | ||||
| ) | ||||
|  | ||||
| const TC_LINKLAYER_MASK = 0x0F | ||||
|  | ||||
| // Police | ||||
| const ( | ||||
| 	TCA_POLICE_UNSPEC = iota | ||||
| 	TCA_POLICE_TBF | ||||
| 	TCA_POLICE_RATE | ||||
| 	TCA_POLICE_PEAKRATE | ||||
| 	TCA_POLICE_AVRATE | ||||
| 	TCA_POLICE_RESULT | ||||
| 	TCA_POLICE_MAX = TCA_POLICE_RESULT | ||||
| ) | ||||
|  | ||||
| // Message types | ||||
| const ( | ||||
| 	TCA_UNSPEC = iota | ||||
| 	TCA_KIND | ||||
| 	TCA_OPTIONS | ||||
| 	TCA_STATS | ||||
| 	TCA_XSTATS | ||||
| 	TCA_RATE | ||||
| 	TCA_FCNT | ||||
| 	TCA_STATS2 | ||||
| 	TCA_STAB | ||||
| 	TCA_MAX = TCA_STAB | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	TCA_ACT_TAB = 1 | ||||
| 	TCAA_MAX    = 1 | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	TCA_PRIO_UNSPEC = iota | ||||
| 	TCA_PRIO_MQ | ||||
| 	TCA_PRIO_MAX = TCA_PRIO_MQ | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	SizeofTcMsg          = 0x14 | ||||
| 	SizeofTcActionMsg    = 0x04 | ||||
| 	SizeofTcPrioMap      = 0x14 | ||||
| 	SizeofTcRateSpec     = 0x0c | ||||
| 	SizeofTcNetemQopt    = 0x18 | ||||
| 	SizeofTcNetemCorr    = 0x0c | ||||
| 	SizeofTcNetemReorder = 0x08 | ||||
| 	SizeofTcNetemCorrupt = 0x08 | ||||
| 	SizeofTcTbfQopt      = 2*SizeofTcRateSpec + 0x0c | ||||
| 	SizeofTcHtbCopt      = 2*SizeofTcRateSpec + 0x14 | ||||
| 	SizeofTcHtbGlob      = 0x14 | ||||
| 	SizeofTcU32Key       = 0x10 | ||||
| 	SizeofTcU32Sel       = 0x10 // without keys | ||||
| 	SizeofTcMirred       = 0x1c | ||||
| 	SizeofTcPolice       = 2*SizeofTcRateSpec + 0x20 | ||||
| ) | ||||
|  | ||||
| // struct tcmsg { | ||||
| //   unsigned char tcm_family; | ||||
| //   unsigned char tcm__pad1; | ||||
| //   unsigned short  tcm__pad2; | ||||
| //   int   tcm_ifindex; | ||||
| //   __u32   tcm_handle; | ||||
| //   __u32   tcm_parent; | ||||
| //   __u32   tcm_info; | ||||
| // }; | ||||
|  | ||||
| type TcMsg struct { | ||||
| 	Family  uint8 | ||||
| 	Pad     [3]byte | ||||
| 	Ifindex int32 | ||||
| 	Handle  uint32 | ||||
| 	Parent  uint32 | ||||
| 	Info    uint32 | ||||
| } | ||||
|  | ||||
| func (msg *TcMsg) Len() int { | ||||
| 	return SizeofTcMsg | ||||
| } | ||||
|  | ||||
| func DeserializeTcMsg(b []byte) *TcMsg { | ||||
| 	return (*TcMsg)(unsafe.Pointer(&b[0:SizeofTcMsg][0])) | ||||
| } | ||||
|  | ||||
| func (x *TcMsg) Serialize() []byte { | ||||
| 	return (*(*[SizeofTcMsg]byte)(unsafe.Pointer(x)))[:] | ||||
| } | ||||
|  | ||||
| // struct tcamsg { | ||||
| //   unsigned char tca_family; | ||||
| //   unsigned char tca__pad1; | ||||
| //   unsigned short  tca__pad2; | ||||
| // }; | ||||
|  | ||||
| type TcActionMsg struct { | ||||
| 	Family uint8 | ||||
| 	Pad    [3]byte | ||||
| } | ||||
|  | ||||
| func (msg *TcActionMsg) Len() int { | ||||
| 	return SizeofTcActionMsg | ||||
| } | ||||
|  | ||||
| func DeserializeTcActionMsg(b []byte) *TcActionMsg { | ||||
| 	return (*TcActionMsg)(unsafe.Pointer(&b[0:SizeofTcActionMsg][0])) | ||||
| } | ||||
|  | ||||
| func (x *TcActionMsg) Serialize() []byte { | ||||
| 	return (*(*[SizeofTcActionMsg]byte)(unsafe.Pointer(x)))[:] | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	TC_PRIO_MAX = 15 | ||||
| ) | ||||
|  | ||||
| // struct tc_prio_qopt { | ||||
| // 	int bands;      /* Number of bands */ | ||||
| // 	__u8  priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */ | ||||
| // }; | ||||
|  | ||||
| type TcPrioMap struct { | ||||
| 	Bands   int32 | ||||
| 	Priomap [TC_PRIO_MAX + 1]uint8 | ||||
| } | ||||
|  | ||||
| func (msg *TcPrioMap) Len() int { | ||||
| 	return SizeofTcPrioMap | ||||
| } | ||||
|  | ||||
| func DeserializeTcPrioMap(b []byte) *TcPrioMap { | ||||
| 	return (*TcPrioMap)(unsafe.Pointer(&b[0:SizeofTcPrioMap][0])) | ||||
| } | ||||
|  | ||||
| func (x *TcPrioMap) Serialize() []byte { | ||||
| 	return (*(*[SizeofTcPrioMap]byte)(unsafe.Pointer(x)))[:] | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	TCA_TBF_UNSPEC = iota | ||||
| 	TCA_TBF_PARMS | ||||
| 	TCA_TBF_RTAB | ||||
| 	TCA_TBF_PTAB | ||||
| 	TCA_TBF_RATE64 | ||||
| 	TCA_TBF_PRATE64 | ||||
| 	TCA_TBF_BURST | ||||
| 	TCA_TBF_PBURST | ||||
| 	TCA_TBF_MAX = TCA_TBF_PBURST | ||||
| ) | ||||
|  | ||||
| // struct tc_ratespec { | ||||
| //   unsigned char cell_log; | ||||
| //   __u8    linklayer; /* lower 4 bits */ | ||||
| //   unsigned short  overhead; | ||||
| //   short   cell_align; | ||||
| //   unsigned short  mpu; | ||||
| //   __u32   rate; | ||||
| // }; | ||||
|  | ||||
| type TcRateSpec struct { | ||||
| 	CellLog   uint8 | ||||
| 	Linklayer uint8 | ||||
| 	Overhead  uint16 | ||||
| 	CellAlign int16 | ||||
| 	Mpu       uint16 | ||||
| 	Rate      uint32 | ||||
| } | ||||
|  | ||||
| func (msg *TcRateSpec) Len() int { | ||||
| 	return SizeofTcRateSpec | ||||
| } | ||||
|  | ||||
| func DeserializeTcRateSpec(b []byte) *TcRateSpec { | ||||
| 	return (*TcRateSpec)(unsafe.Pointer(&b[0:SizeofTcRateSpec][0])) | ||||
| } | ||||
|  | ||||
| func (x *TcRateSpec) Serialize() []byte { | ||||
| 	return (*(*[SizeofTcRateSpec]byte)(unsafe.Pointer(x)))[:] | ||||
| } | ||||
|  | ||||
| /** | ||||
| * NETEM | ||||
|  */ | ||||
|  | ||||
| const ( | ||||
| 	TCA_NETEM_UNSPEC = iota | ||||
| 	TCA_NETEM_CORR | ||||
| 	TCA_NETEM_DELAY_DIST | ||||
| 	TCA_NETEM_REORDER | ||||
| 	TCA_NETEM_CORRUPT | ||||
| 	TCA_NETEM_LOSS | ||||
| 	TCA_NETEM_RATE | ||||
| 	TCA_NETEM_ECN | ||||
| 	TCA_NETEM_RATE64 | ||||
| 	TCA_NETEM_MAX = TCA_NETEM_RATE64 | ||||
| ) | ||||
|  | ||||
| // struct tc_netem_qopt { | ||||
| //	__u32	latency;	/* added delay (us) */ | ||||
| //	__u32   limit;		/* fifo limit (packets) */ | ||||
| //	__u32	loss;		/* random packet loss (0=none ~0=100%) */ | ||||
| //	__u32	gap;		/* re-ordering gap (0 for none) */ | ||||
| //	__u32   duplicate;	/* random packet dup  (0=none ~0=100%) */ | ||||
| // 	__u32	jitter;		/* random jitter in latency (us) */ | ||||
| // }; | ||||
|  | ||||
| type TcNetemQopt struct { | ||||
| 	Latency   uint32 | ||||
| 	Limit     uint32 | ||||
| 	Loss      uint32 | ||||
| 	Gap       uint32 | ||||
| 	Duplicate uint32 | ||||
| 	Jitter    uint32 | ||||
| } | ||||
|  | ||||
| func (msg *TcNetemQopt) Len() int { | ||||
| 	return SizeofTcNetemQopt | ||||
| } | ||||
|  | ||||
| func DeserializeTcNetemQopt(b []byte) *TcNetemQopt { | ||||
| 	return (*TcNetemQopt)(unsafe.Pointer(&b[0:SizeofTcNetemQopt][0])) | ||||
| } | ||||
|  | ||||
| func (x *TcNetemQopt) Serialize() []byte { | ||||
| 	return (*(*[SizeofTcNetemQopt]byte)(unsafe.Pointer(x)))[:] | ||||
| } | ||||
|  | ||||
| // struct tc_netem_corr { | ||||
| //  __u32   delay_corr; /* delay correlation */ | ||||
| //  __u32   loss_corr;  /* packet loss correlation */ | ||||
| //  __u32   dup_corr;   /* duplicate correlation  */ | ||||
| // }; | ||||
|  | ||||
| type TcNetemCorr struct { | ||||
| 	DelayCorr uint32 | ||||
| 	LossCorr  uint32 | ||||
| 	DupCorr   uint32 | ||||
| } | ||||
|  | ||||
| func (msg *TcNetemCorr) Len() int { | ||||
| 	return SizeofTcNetemCorr | ||||
| } | ||||
|  | ||||
| func DeserializeTcNetemCorr(b []byte) *TcNetemCorr { | ||||
| 	return (*TcNetemCorr)(unsafe.Pointer(&b[0:SizeofTcNetemCorr][0])) | ||||
| } | ||||
|  | ||||
| func (x *TcNetemCorr) Serialize() []byte { | ||||
| 	return (*(*[SizeofTcNetemCorr]byte)(unsafe.Pointer(x)))[:] | ||||
| } | ||||
|  | ||||
| // struct tc_netem_reorder { | ||||
| //  __u32   probability; | ||||
| //  __u32   correlation; | ||||
| // }; | ||||
|  | ||||
| type TcNetemReorder struct { | ||||
| 	Probability uint32 | ||||
| 	Correlation uint32 | ||||
| } | ||||
|  | ||||
| func (msg *TcNetemReorder) Len() int { | ||||
| 	return SizeofTcNetemReorder | ||||
| } | ||||
|  | ||||
| func DeserializeTcNetemReorder(b []byte) *TcNetemReorder { | ||||
| 	return (*TcNetemReorder)(unsafe.Pointer(&b[0:SizeofTcNetemReorder][0])) | ||||
| } | ||||
|  | ||||
| func (x *TcNetemReorder) Serialize() []byte { | ||||
| 	return (*(*[SizeofTcNetemReorder]byte)(unsafe.Pointer(x)))[:] | ||||
| } | ||||
|  | ||||
| // struct tc_netem_corrupt { | ||||
| //  __u32   probability; | ||||
| //  __u32   correlation; | ||||
| // }; | ||||
|  | ||||
| type TcNetemCorrupt struct { | ||||
| 	Probability uint32 | ||||
| 	Correlation uint32 | ||||
| } | ||||
|  | ||||
| func (msg *TcNetemCorrupt) Len() int { | ||||
| 	return SizeofTcNetemCorrupt | ||||
| } | ||||
|  | ||||
| func DeserializeTcNetemCorrupt(b []byte) *TcNetemCorrupt { | ||||
| 	return (*TcNetemCorrupt)(unsafe.Pointer(&b[0:SizeofTcNetemCorrupt][0])) | ||||
| } | ||||
|  | ||||
| func (x *TcNetemCorrupt) Serialize() []byte { | ||||
| 	return (*(*[SizeofTcNetemCorrupt]byte)(unsafe.Pointer(x)))[:] | ||||
| } | ||||
|  | ||||
| // struct tc_tbf_qopt { | ||||
| //   struct tc_ratespec rate; | ||||
| //   struct tc_ratespec peakrate; | ||||
| //   __u32   limit; | ||||
| //   __u32   buffer; | ||||
| //   __u32   mtu; | ||||
| // }; | ||||
|  | ||||
| type TcTbfQopt struct { | ||||
| 	Rate     TcRateSpec | ||||
| 	Peakrate TcRateSpec | ||||
| 	Limit    uint32 | ||||
| 	Buffer   uint32 | ||||
| 	Mtu      uint32 | ||||
| } | ||||
|  | ||||
| func (msg *TcTbfQopt) Len() int { | ||||
| 	return SizeofTcTbfQopt | ||||
| } | ||||
|  | ||||
| func DeserializeTcTbfQopt(b []byte) *TcTbfQopt { | ||||
| 	return (*TcTbfQopt)(unsafe.Pointer(&b[0:SizeofTcTbfQopt][0])) | ||||
| } | ||||
|  | ||||
| func (x *TcTbfQopt) Serialize() []byte { | ||||
| 	return (*(*[SizeofTcTbfQopt]byte)(unsafe.Pointer(x)))[:] | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	TCA_HTB_UNSPEC = iota | ||||
| 	TCA_HTB_PARMS | ||||
| 	TCA_HTB_INIT | ||||
| 	TCA_HTB_CTAB | ||||
| 	TCA_HTB_RTAB | ||||
| 	TCA_HTB_DIRECT_QLEN | ||||
| 	TCA_HTB_RATE64 | ||||
| 	TCA_HTB_CEIL64 | ||||
| 	TCA_HTB_MAX = TCA_HTB_CEIL64 | ||||
| ) | ||||
|  | ||||
| //struct tc_htb_opt { | ||||
| //	struct tc_ratespec	rate; | ||||
| //	struct tc_ratespec	ceil; | ||||
| //	__u32	buffer; | ||||
| //	__u32	cbuffer; | ||||
| //	__u32	quantum; | ||||
| //	__u32	level;		/* out only */ | ||||
| //	__u32	prio; | ||||
| //}; | ||||
|  | ||||
| type TcHtbCopt struct { | ||||
| 	Rate    TcRateSpec | ||||
| 	Ceil    TcRateSpec | ||||
| 	Buffer  uint32 | ||||
| 	Cbuffer uint32 | ||||
| 	Quantum uint32 | ||||
| 	Level   uint32 | ||||
| 	Prio    uint32 | ||||
| } | ||||
|  | ||||
| func (msg *TcHtbCopt) Len() int { | ||||
| 	return SizeofTcHtbCopt | ||||
| } | ||||
|  | ||||
| func DeserializeTcHtbCopt(b []byte) *TcHtbCopt { | ||||
| 	return (*TcHtbCopt)(unsafe.Pointer(&b[0:SizeofTcHtbCopt][0])) | ||||
| } | ||||
|  | ||||
| func (x *TcHtbCopt) Serialize() []byte { | ||||
| 	return (*(*[SizeofTcHtbCopt]byte)(unsafe.Pointer(x)))[:] | ||||
| } | ||||
|  | ||||
| type TcHtbGlob struct { | ||||
| 	Version      uint32 | ||||
| 	Rate2Quantum uint32 | ||||
| 	Defcls       uint32 | ||||
| 	Debug        uint32 | ||||
| 	DirectPkts   uint32 | ||||
| } | ||||
|  | ||||
| func (msg *TcHtbGlob) Len() int { | ||||
| 	return SizeofTcHtbGlob | ||||
| } | ||||
|  | ||||
| func DeserializeTcHtbGlob(b []byte) *TcHtbGlob { | ||||
| 	return (*TcHtbGlob)(unsafe.Pointer(&b[0:SizeofTcHtbGlob][0])) | ||||
| } | ||||
|  | ||||
| func (x *TcHtbGlob) Serialize() []byte { | ||||
| 	return (*(*[SizeofTcHtbGlob]byte)(unsafe.Pointer(x)))[:] | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	TCA_U32_UNSPEC = iota | ||||
| 	TCA_U32_CLASSID | ||||
| 	TCA_U32_HASH | ||||
| 	TCA_U32_LINK | ||||
| 	TCA_U32_DIVISOR | ||||
| 	TCA_U32_SEL | ||||
| 	TCA_U32_POLICE | ||||
| 	TCA_U32_ACT | ||||
| 	TCA_U32_INDEV | ||||
| 	TCA_U32_PCNT | ||||
| 	TCA_U32_MARK | ||||
| 	TCA_U32_MAX = TCA_U32_MARK | ||||
| ) | ||||
|  | ||||
| // struct tc_u32_key { | ||||
| //   __be32    mask; | ||||
| //   __be32    val; | ||||
| //   int   off; | ||||
| //   int   offmask; | ||||
| // }; | ||||
|  | ||||
| type TcU32Key struct { | ||||
| 	Mask    uint32 // big endian | ||||
| 	Val     uint32 // big endian | ||||
| 	Off     int32 | ||||
| 	OffMask int32 | ||||
| } | ||||
|  | ||||
| func (msg *TcU32Key) Len() int { | ||||
| 	return SizeofTcU32Key | ||||
| } | ||||
|  | ||||
| func DeserializeTcU32Key(b []byte) *TcU32Key { | ||||
| 	return (*TcU32Key)(unsafe.Pointer(&b[0:SizeofTcU32Key][0])) | ||||
| } | ||||
|  | ||||
| func (x *TcU32Key) Serialize() []byte { | ||||
| 	return (*(*[SizeofTcU32Key]byte)(unsafe.Pointer(x)))[:] | ||||
| } | ||||
|  | ||||
| // struct tc_u32_sel { | ||||
| //   unsigned char   flags; | ||||
| //   unsigned char   offshift; | ||||
| //   unsigned char   nkeys; | ||||
| // | ||||
| //   __be16      offmask; | ||||
| //   __u16     off; | ||||
| //   short     offoff; | ||||
| // | ||||
| //   short     hoff; | ||||
| //   __be32      hmask; | ||||
| //   struct tc_u32_key keys[0]; | ||||
| // }; | ||||
|  | ||||
| const ( | ||||
| 	TC_U32_TERMINAL  = 1 << iota | ||||
| 	TC_U32_OFFSET    = 1 << iota | ||||
| 	TC_U32_VAROFFSET = 1 << iota | ||||
| 	TC_U32_EAT       = 1 << iota | ||||
| ) | ||||
|  | ||||
| type TcU32Sel struct { | ||||
| 	Flags    uint8 | ||||
| 	Offshift uint8 | ||||
| 	Nkeys    uint8 | ||||
| 	Pad      uint8 | ||||
| 	Offmask  uint16 // big endian | ||||
| 	Off      uint16 | ||||
| 	Offoff   int16 | ||||
| 	Hoff     int16 | ||||
| 	Hmask    uint32 // big endian | ||||
| 	Keys     []TcU32Key | ||||
| } | ||||
|  | ||||
| func (msg *TcU32Sel) Len() int { | ||||
| 	return SizeofTcU32Sel + int(msg.Nkeys)*SizeofTcU32Key | ||||
| } | ||||
|  | ||||
| func DeserializeTcU32Sel(b []byte) *TcU32Sel { | ||||
| 	x := &TcU32Sel{} | ||||
| 	copy((*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:], b) | ||||
| 	next := SizeofTcU32Sel | ||||
| 	var i uint8 | ||||
| 	for i = 0; i < x.Nkeys; i++ { | ||||
| 		x.Keys = append(x.Keys, *DeserializeTcU32Key(b[next:])) | ||||
| 		next += SizeofTcU32Key | ||||
| 	} | ||||
| 	return x | ||||
| } | ||||
|  | ||||
| func (x *TcU32Sel) Serialize() []byte { | ||||
| 	// This can't just unsafe.cast because it must iterate through keys. | ||||
| 	buf := make([]byte, x.Len()) | ||||
| 	copy(buf, (*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:]) | ||||
| 	next := SizeofTcU32Sel | ||||
| 	for _, key := range x.Keys { | ||||
| 		keyBuf := key.Serialize() | ||||
| 		copy(buf[next:], keyBuf) | ||||
| 		next += SizeofTcU32Key | ||||
| 	} | ||||
| 	return buf | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	TCA_ACT_MIRRED = 8 | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	TCA_MIRRED_UNSPEC = iota | ||||
| 	TCA_MIRRED_TM | ||||
| 	TCA_MIRRED_PARMS | ||||
| 	TCA_MIRRED_MAX = TCA_MIRRED_PARMS | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	TCA_EGRESS_REDIR   = 1 /* packet redirect to EGRESS*/ | ||||
| 	TCA_EGRESS_MIRROR  = 2 /* mirror packet to EGRESS */ | ||||
| 	TCA_INGRESS_REDIR  = 3 /* packet redirect to INGRESS*/ | ||||
| 	TCA_INGRESS_MIRROR = 4 /* mirror packet to INGRESS */ | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	TC_ACT_UNSPEC     = int32(-1) | ||||
| 	TC_ACT_OK         = 0 | ||||
| 	TC_ACT_RECLASSIFY = 1 | ||||
| 	TC_ACT_SHOT       = 2 | ||||
| 	TC_ACT_PIPE       = 3 | ||||
| 	TC_ACT_STOLEN     = 4 | ||||
| 	TC_ACT_QUEUED     = 5 | ||||
| 	TC_ACT_REPEAT     = 6 | ||||
| 	TC_ACT_JUMP       = 0x10000000 | ||||
| ) | ||||
|  | ||||
| // #define tc_gen \ | ||||
| //   __u32                 index; \ | ||||
| //   __u32                 capab; \ | ||||
| //   int                   action; \ | ||||
| //   int                   refcnt; \ | ||||
| //   int                   bindcnt | ||||
| // struct tc_mirred { | ||||
| // 	tc_gen; | ||||
| // 	int                     eaction;   /* one of IN/EGRESS_MIRROR/REDIR */ | ||||
| // 	__u32                   ifindex;  /* ifindex of egress port */ | ||||
| // }; | ||||
|  | ||||
| type TcMirred struct { | ||||
| 	Index   uint32 | ||||
| 	Capab   uint32 | ||||
| 	Action  int32 | ||||
| 	Refcnt  int32 | ||||
| 	Bindcnt int32 | ||||
| 	Eaction int32 | ||||
| 	Ifindex uint32 | ||||
| } | ||||
|  | ||||
| func (msg *TcMirred) Len() int { | ||||
| 	return SizeofTcMirred | ||||
| } | ||||
|  | ||||
| func DeserializeTcMirred(b []byte) *TcMirred { | ||||
| 	return (*TcMirred)(unsafe.Pointer(&b[0:SizeofTcMirred][0])) | ||||
| } | ||||
|  | ||||
| func (x *TcMirred) Serialize() []byte { | ||||
| 	return (*(*[SizeofTcMirred]byte)(unsafe.Pointer(x)))[:] | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	TC_POLICE_UNSPEC     = TC_ACT_UNSPEC | ||||
| 	TC_POLICE_OK         = TC_ACT_OK | ||||
| 	TC_POLICE_RECLASSIFY = TC_ACT_RECLASSIFY | ||||
| 	TC_POLICE_SHOT       = TC_ACT_SHOT | ||||
| 	TC_POLICE_PIPE       = TC_ACT_PIPE | ||||
| ) | ||||
|  | ||||
| // struct tc_police { | ||||
| // 	__u32			index; | ||||
| // 	int			action; | ||||
| // 	__u32			limit; | ||||
| // 	__u32			burst; | ||||
| // 	__u32			mtu; | ||||
| // 	struct tc_ratespec	rate; | ||||
| // 	struct tc_ratespec	peakrate; | ||||
| // 	int				refcnt; | ||||
| // 	int				bindcnt; | ||||
| // 	__u32			capab; | ||||
| // }; | ||||
|  | ||||
| type TcPolice struct { | ||||
| 	Index    uint32 | ||||
| 	Action   int32 | ||||
| 	Limit    uint32 | ||||
| 	Burst    uint32 | ||||
| 	Mtu      uint32 | ||||
| 	Rate     TcRateSpec | ||||
| 	PeakRate TcRateSpec | ||||
| 	Refcnt   int32 | ||||
| 	Bindcnt  int32 | ||||
| 	Capab    uint32 | ||||
| } | ||||
|  | ||||
| func (msg *TcPolice) Len() int { | ||||
| 	return SizeofTcPolice | ||||
| } | ||||
|  | ||||
| func DeserializeTcPolice(b []byte) *TcPolice { | ||||
| 	return (*TcPolice)(unsafe.Pointer(&b[0:SizeofTcPolice][0])) | ||||
| } | ||||
|  | ||||
| func (x *TcPolice) Serialize() []byte { | ||||
| 	return (*(*[SizeofTcPolice]byte)(unsafe.Pointer(x)))[:] | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	TCA_FW_UNSPEC = iota | ||||
| 	TCA_FW_CLASSID | ||||
| 	TCA_FW_POLICE | ||||
| 	TCA_FW_INDEV | ||||
| 	TCA_FW_ACT | ||||
| 	TCA_FW_MASK | ||||
| 	TCA_FW_MAX = TCA_FW_MASK | ||||
| ) | ||||
							
								
								
									
										258
									
								
								vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										258
									
								
								vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,258 +0,0 @@ | ||||
| package nl | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"net" | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| // Infinity for packet and byte counts | ||||
| const ( | ||||
| 	XFRM_INF = ^uint64(0) | ||||
| ) | ||||
|  | ||||
| // Message Types | ||||
| const ( | ||||
| 	XFRM_MSG_BASE        = 0x10 | ||||
| 	XFRM_MSG_NEWSA       = 0x10 | ||||
| 	XFRM_MSG_DELSA       = 0x11 | ||||
| 	XFRM_MSG_GETSA       = 0x12 | ||||
| 	XFRM_MSG_NEWPOLICY   = 0x13 | ||||
| 	XFRM_MSG_DELPOLICY   = 0x14 | ||||
| 	XFRM_MSG_GETPOLICY   = 0x15 | ||||
| 	XFRM_MSG_ALLOCSPI    = 0x16 | ||||
| 	XFRM_MSG_ACQUIRE     = 0x17 | ||||
| 	XFRM_MSG_EXPIRE      = 0x18 | ||||
| 	XFRM_MSG_UPDPOLICY   = 0x19 | ||||
| 	XFRM_MSG_UPDSA       = 0x1a | ||||
| 	XFRM_MSG_POLEXPIRE   = 0x1b | ||||
| 	XFRM_MSG_FLUSHSA     = 0x1c | ||||
| 	XFRM_MSG_FLUSHPOLICY = 0x1d | ||||
| 	XFRM_MSG_NEWAE       = 0x1e | ||||
| 	XFRM_MSG_GETAE       = 0x1f | ||||
| 	XFRM_MSG_REPORT      = 0x20 | ||||
| 	XFRM_MSG_MIGRATE     = 0x21 | ||||
| 	XFRM_MSG_NEWSADINFO  = 0x22 | ||||
| 	XFRM_MSG_GETSADINFO  = 0x23 | ||||
| 	XFRM_MSG_NEWSPDINFO  = 0x24 | ||||
| 	XFRM_MSG_GETSPDINFO  = 0x25 | ||||
| 	XFRM_MSG_MAPPING     = 0x26 | ||||
| 	XFRM_MSG_MAX         = 0x26 | ||||
| 	XFRM_NR_MSGTYPES     = 0x17 | ||||
| ) | ||||
|  | ||||
| // Attribute types | ||||
| const ( | ||||
| 	/* Netlink message attributes.  */ | ||||
| 	XFRMA_UNSPEC         = 0x00 | ||||
| 	XFRMA_ALG_AUTH       = 0x01 /* struct xfrm_algo */ | ||||
| 	XFRMA_ALG_CRYPT      = 0x02 /* struct xfrm_algo */ | ||||
| 	XFRMA_ALG_COMP       = 0x03 /* struct xfrm_algo */ | ||||
| 	XFRMA_ENCAP          = 0x04 /* struct xfrm_algo + struct xfrm_encap_tmpl */ | ||||
| 	XFRMA_TMPL           = 0x05 /* 1 or more struct xfrm_user_tmpl */ | ||||
| 	XFRMA_SA             = 0x06 /* struct xfrm_usersa_info  */ | ||||
| 	XFRMA_POLICY         = 0x07 /* struct xfrm_userpolicy_info */ | ||||
| 	XFRMA_SEC_CTX        = 0x08 /* struct xfrm_sec_ctx */ | ||||
| 	XFRMA_LTIME_VAL      = 0x09 | ||||
| 	XFRMA_REPLAY_VAL     = 0x0a | ||||
| 	XFRMA_REPLAY_THRESH  = 0x0b | ||||
| 	XFRMA_ETIMER_THRESH  = 0x0c | ||||
| 	XFRMA_SRCADDR        = 0x0d /* xfrm_address_t */ | ||||
| 	XFRMA_COADDR         = 0x0e /* xfrm_address_t */ | ||||
| 	XFRMA_LASTUSED       = 0x0f /* unsigned long  */ | ||||
| 	XFRMA_POLICY_TYPE    = 0x10 /* struct xfrm_userpolicy_type */ | ||||
| 	XFRMA_MIGRATE        = 0x11 | ||||
| 	XFRMA_ALG_AEAD       = 0x12 /* struct xfrm_algo_aead */ | ||||
| 	XFRMA_KMADDRESS      = 0x13 /* struct xfrm_user_kmaddress */ | ||||
| 	XFRMA_ALG_AUTH_TRUNC = 0x14 /* struct xfrm_algo_auth */ | ||||
| 	XFRMA_MARK           = 0x15 /* struct xfrm_mark */ | ||||
| 	XFRMA_TFCPAD         = 0x16 /* __u32 */ | ||||
| 	XFRMA_REPLAY_ESN_VAL = 0x17 /* struct xfrm_replay_esn */ | ||||
| 	XFRMA_SA_EXTRA_FLAGS = 0x18 /* __u32 */ | ||||
| 	XFRMA_MAX            = 0x18 | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	SizeofXfrmAddress     = 0x10 | ||||
| 	SizeofXfrmSelector    = 0x38 | ||||
| 	SizeofXfrmLifetimeCfg = 0x40 | ||||
| 	SizeofXfrmLifetimeCur = 0x20 | ||||
| 	SizeofXfrmId          = 0x18 | ||||
| ) | ||||
|  | ||||
| // typedef union { | ||||
| //   __be32    a4; | ||||
| //   __be32    a6[4]; | ||||
| // } xfrm_address_t; | ||||
|  | ||||
| type XfrmAddress [SizeofXfrmAddress]byte | ||||
|  | ||||
| func (x *XfrmAddress) ToIP() net.IP { | ||||
| 	var empty = [12]byte{} | ||||
| 	ip := make(net.IP, net.IPv6len) | ||||
| 	if bytes.Equal(x[4:16], empty[:]) { | ||||
| 		ip[10] = 0xff | ||||
| 		ip[11] = 0xff | ||||
| 		copy(ip[12:16], x[0:4]) | ||||
| 	} else { | ||||
| 		copy(ip[:], x[:]) | ||||
| 	} | ||||
| 	return ip | ||||
| } | ||||
|  | ||||
| func (x *XfrmAddress) ToIPNet(prefixlen uint8) *net.IPNet { | ||||
| 	ip := x.ToIP() | ||||
| 	if GetIPFamily(ip) == FAMILY_V4 { | ||||
| 		return &net.IPNet{IP: ip, Mask: net.CIDRMask(int(prefixlen), 32)} | ||||
| 	} | ||||
| 	return &net.IPNet{IP: ip, Mask: net.CIDRMask(int(prefixlen), 128)} | ||||
| } | ||||
|  | ||||
| func (x *XfrmAddress) FromIP(ip net.IP) { | ||||
| 	var empty = [16]byte{} | ||||
| 	if len(ip) < net.IPv4len { | ||||
| 		copy(x[4:16], empty[:]) | ||||
| 	} else if GetIPFamily(ip) == FAMILY_V4 { | ||||
| 		copy(x[0:4], ip.To4()[0:4]) | ||||
| 		copy(x[4:16], empty[:12]) | ||||
| 	} else { | ||||
| 		copy(x[0:16], ip.To16()[0:16]) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func DeserializeXfrmAddress(b []byte) *XfrmAddress { | ||||
| 	return (*XfrmAddress)(unsafe.Pointer(&b[0:SizeofXfrmAddress][0])) | ||||
| } | ||||
|  | ||||
| func (x *XfrmAddress) Serialize() []byte { | ||||
| 	return (*(*[SizeofXfrmAddress]byte)(unsafe.Pointer(x)))[:] | ||||
| } | ||||
|  | ||||
| // struct xfrm_selector { | ||||
| //   xfrm_address_t  daddr; | ||||
| //   xfrm_address_t  saddr; | ||||
| //   __be16  dport; | ||||
| //   __be16  dport_mask; | ||||
| //   __be16  sport; | ||||
| //   __be16  sport_mask; | ||||
| //   __u16 family; | ||||
| //   __u8  prefixlen_d; | ||||
| //   __u8  prefixlen_s; | ||||
| //   __u8  proto; | ||||
| //   int ifindex; | ||||
| //   __kernel_uid32_t  user; | ||||
| // }; | ||||
|  | ||||
| type XfrmSelector struct { | ||||
| 	Daddr      XfrmAddress | ||||
| 	Saddr      XfrmAddress | ||||
| 	Dport      uint16 // big endian | ||||
| 	DportMask  uint16 // big endian | ||||
| 	Sport      uint16 // big endian | ||||
| 	SportMask  uint16 // big endian | ||||
| 	Family     uint16 | ||||
| 	PrefixlenD uint8 | ||||
| 	PrefixlenS uint8 | ||||
| 	Proto      uint8 | ||||
| 	Pad        [3]byte | ||||
| 	Ifindex    int32 | ||||
| 	User       uint32 | ||||
| } | ||||
|  | ||||
| func (msg *XfrmSelector) Len() int { | ||||
| 	return SizeofXfrmSelector | ||||
| } | ||||
|  | ||||
| func DeserializeXfrmSelector(b []byte) *XfrmSelector { | ||||
| 	return (*XfrmSelector)(unsafe.Pointer(&b[0:SizeofXfrmSelector][0])) | ||||
| } | ||||
|  | ||||
| func (msg *XfrmSelector) Serialize() []byte { | ||||
| 	return (*(*[SizeofXfrmSelector]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
|  | ||||
| // struct xfrm_lifetime_cfg { | ||||
| //   __u64 soft_byte_limit; | ||||
| //   __u64 hard_byte_limit; | ||||
| //   __u64 soft_packet_limit; | ||||
| //   __u64 hard_packet_limit; | ||||
| //   __u64 soft_add_expires_seconds; | ||||
| //   __u64 hard_add_expires_seconds; | ||||
| //   __u64 soft_use_expires_seconds; | ||||
| //   __u64 hard_use_expires_seconds; | ||||
| // }; | ||||
| // | ||||
|  | ||||
| type XfrmLifetimeCfg struct { | ||||
| 	SoftByteLimit         uint64 | ||||
| 	HardByteLimit         uint64 | ||||
| 	SoftPacketLimit       uint64 | ||||
| 	HardPacketLimit       uint64 | ||||
| 	SoftAddExpiresSeconds uint64 | ||||
| 	HardAddExpiresSeconds uint64 | ||||
| 	SoftUseExpiresSeconds uint64 | ||||
| 	HardUseExpiresSeconds uint64 | ||||
| } | ||||
|  | ||||
| func (msg *XfrmLifetimeCfg) Len() int { | ||||
| 	return SizeofXfrmLifetimeCfg | ||||
| } | ||||
|  | ||||
| func DeserializeXfrmLifetimeCfg(b []byte) *XfrmLifetimeCfg { | ||||
| 	return (*XfrmLifetimeCfg)(unsafe.Pointer(&b[0:SizeofXfrmLifetimeCfg][0])) | ||||
| } | ||||
|  | ||||
| func (msg *XfrmLifetimeCfg) Serialize() []byte { | ||||
| 	return (*(*[SizeofXfrmLifetimeCfg]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
|  | ||||
| // struct xfrm_lifetime_cur { | ||||
| //   __u64 bytes; | ||||
| //   __u64 packets; | ||||
| //   __u64 add_time; | ||||
| //   __u64 use_time; | ||||
| // }; | ||||
|  | ||||
| type XfrmLifetimeCur struct { | ||||
| 	Bytes   uint64 | ||||
| 	Packets uint64 | ||||
| 	AddTime uint64 | ||||
| 	UseTime uint64 | ||||
| } | ||||
|  | ||||
| func (msg *XfrmLifetimeCur) Len() int { | ||||
| 	return SizeofXfrmLifetimeCur | ||||
| } | ||||
|  | ||||
| func DeserializeXfrmLifetimeCur(b []byte) *XfrmLifetimeCur { | ||||
| 	return (*XfrmLifetimeCur)(unsafe.Pointer(&b[0:SizeofXfrmLifetimeCur][0])) | ||||
| } | ||||
|  | ||||
| func (msg *XfrmLifetimeCur) Serialize() []byte { | ||||
| 	return (*(*[SizeofXfrmLifetimeCur]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
|  | ||||
| // struct xfrm_id { | ||||
| //   xfrm_address_t  daddr; | ||||
| //   __be32    spi; | ||||
| //   __u8    proto; | ||||
| // }; | ||||
|  | ||||
| type XfrmId struct { | ||||
| 	Daddr XfrmAddress | ||||
| 	Spi   uint32 // big endian | ||||
| 	Proto uint8 | ||||
| 	Pad   [3]byte | ||||
| } | ||||
|  | ||||
| func (msg *XfrmId) Len() int { | ||||
| 	return SizeofXfrmId | ||||
| } | ||||
|  | ||||
| func DeserializeXfrmId(b []byte) *XfrmId { | ||||
| 	return (*XfrmId)(unsafe.Pointer(&b[0:SizeofXfrmId][0])) | ||||
| } | ||||
|  | ||||
| func (msg *XfrmId) Serialize() []byte { | ||||
| 	return (*(*[SizeofXfrmId]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
							
								
								
									
										119
									
								
								vendor/github.com/vishvananda/netlink/nl/xfrm_policy_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										119
									
								
								vendor/github.com/vishvananda/netlink/nl/xfrm_policy_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,119 +0,0 @@ | ||||
| package nl | ||||
|  | ||||
| import ( | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	SizeofXfrmUserpolicyId   = 0x40 | ||||
| 	SizeofXfrmUserpolicyInfo = 0xa8 | ||||
| 	SizeofXfrmUserTmpl       = 0x40 | ||||
| ) | ||||
|  | ||||
| // struct xfrm_userpolicy_id { | ||||
| //   struct xfrm_selector    sel; | ||||
| //   __u32       index; | ||||
| //   __u8        dir; | ||||
| // }; | ||||
| // | ||||
|  | ||||
| type XfrmUserpolicyId struct { | ||||
| 	Sel   XfrmSelector | ||||
| 	Index uint32 | ||||
| 	Dir   uint8 | ||||
| 	Pad   [3]byte | ||||
| } | ||||
|  | ||||
| func (msg *XfrmUserpolicyId) Len() int { | ||||
| 	return SizeofXfrmUserpolicyId | ||||
| } | ||||
|  | ||||
| func DeserializeXfrmUserpolicyId(b []byte) *XfrmUserpolicyId { | ||||
| 	return (*XfrmUserpolicyId)(unsafe.Pointer(&b[0:SizeofXfrmUserpolicyId][0])) | ||||
| } | ||||
|  | ||||
| func (msg *XfrmUserpolicyId) Serialize() []byte { | ||||
| 	return (*(*[SizeofXfrmUserpolicyId]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
|  | ||||
| // struct xfrm_userpolicy_info { | ||||
| //   struct xfrm_selector    sel; | ||||
| //   struct xfrm_lifetime_cfg  lft; | ||||
| //   struct xfrm_lifetime_cur  curlft; | ||||
| //   __u32       priority; | ||||
| //   __u32       index; | ||||
| //   __u8        dir; | ||||
| //   __u8        action; | ||||
| // #define XFRM_POLICY_ALLOW 0 | ||||
| // #define XFRM_POLICY_BLOCK 1 | ||||
| //   __u8        flags; | ||||
| // #define XFRM_POLICY_LOCALOK 1 /* Allow user to override global policy */ | ||||
| //   /* Automatically expand selector to include matching ICMP payloads. */ | ||||
| // #define XFRM_POLICY_ICMP  2 | ||||
| //   __u8        share; | ||||
| // }; | ||||
|  | ||||
| type XfrmUserpolicyInfo struct { | ||||
| 	Sel      XfrmSelector | ||||
| 	Lft      XfrmLifetimeCfg | ||||
| 	Curlft   XfrmLifetimeCur | ||||
| 	Priority uint32 | ||||
| 	Index    uint32 | ||||
| 	Dir      uint8 | ||||
| 	Action   uint8 | ||||
| 	Flags    uint8 | ||||
| 	Share    uint8 | ||||
| 	Pad      [4]byte | ||||
| } | ||||
|  | ||||
| func (msg *XfrmUserpolicyInfo) Len() int { | ||||
| 	return SizeofXfrmUserpolicyInfo | ||||
| } | ||||
|  | ||||
| func DeserializeXfrmUserpolicyInfo(b []byte) *XfrmUserpolicyInfo { | ||||
| 	return (*XfrmUserpolicyInfo)(unsafe.Pointer(&b[0:SizeofXfrmUserpolicyInfo][0])) | ||||
| } | ||||
|  | ||||
| func (msg *XfrmUserpolicyInfo) Serialize() []byte { | ||||
| 	return (*(*[SizeofXfrmUserpolicyInfo]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
|  | ||||
| // struct xfrm_user_tmpl { | ||||
| //   struct xfrm_id    id; | ||||
| //   __u16     family; | ||||
| //   xfrm_address_t    saddr; | ||||
| //   __u32     reqid; | ||||
| //   __u8      mode; | ||||
| //   __u8      share; | ||||
| //   __u8      optional; | ||||
| //   __u32     aalgos; | ||||
| //   __u32     ealgos; | ||||
| //   __u32     calgos; | ||||
| // } | ||||
|  | ||||
| type XfrmUserTmpl struct { | ||||
| 	XfrmId   XfrmId | ||||
| 	Family   uint16 | ||||
| 	Pad1     [2]byte | ||||
| 	Saddr    XfrmAddress | ||||
| 	Reqid    uint32 | ||||
| 	Mode     uint8 | ||||
| 	Share    uint8 | ||||
| 	Optional uint8 | ||||
| 	Pad2     byte | ||||
| 	Aalgos   uint32 | ||||
| 	Ealgos   uint32 | ||||
| 	Calgos   uint32 | ||||
| } | ||||
|  | ||||
| func (msg *XfrmUserTmpl) Len() int { | ||||
| 	return SizeofXfrmUserTmpl | ||||
| } | ||||
|  | ||||
| func DeserializeXfrmUserTmpl(b []byte) *XfrmUserTmpl { | ||||
| 	return (*XfrmUserTmpl)(unsafe.Pointer(&b[0:SizeofXfrmUserTmpl][0])) | ||||
| } | ||||
|  | ||||
| func (msg *XfrmUserTmpl) Serialize() []byte { | ||||
| 	return (*(*[SizeofXfrmUserTmpl]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
							
								
								
									
										221
									
								
								vendor/github.com/vishvananda/netlink/nl/xfrm_state_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										221
									
								
								vendor/github.com/vishvananda/netlink/nl/xfrm_state_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,221 +0,0 @@ | ||||
| package nl | ||||
|  | ||||
| import ( | ||||
| 	"unsafe" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	SizeofXfrmUsersaId   = 0x18 | ||||
| 	SizeofXfrmStats      = 0x0c | ||||
| 	SizeofXfrmUsersaInfo = 0xe0 | ||||
| 	SizeofXfrmAlgo       = 0x44 | ||||
| 	SizeofXfrmAlgoAuth   = 0x48 | ||||
| 	SizeofXfrmEncapTmpl  = 0x18 | ||||
| ) | ||||
|  | ||||
| // struct xfrm_usersa_id { | ||||
| //   xfrm_address_t      daddr; | ||||
| //   __be32        spi; | ||||
| //   __u16       family; | ||||
| //   __u8        proto; | ||||
| // }; | ||||
|  | ||||
| type XfrmUsersaId struct { | ||||
| 	Daddr  XfrmAddress | ||||
| 	Spi    uint32 // big endian | ||||
| 	Family uint16 | ||||
| 	Proto  uint8 | ||||
| 	Pad    byte | ||||
| } | ||||
|  | ||||
| func (msg *XfrmUsersaId) Len() int { | ||||
| 	return SizeofXfrmUsersaId | ||||
| } | ||||
|  | ||||
| func DeserializeXfrmUsersaId(b []byte) *XfrmUsersaId { | ||||
| 	return (*XfrmUsersaId)(unsafe.Pointer(&b[0:SizeofXfrmUsersaId][0])) | ||||
| } | ||||
|  | ||||
| func (msg *XfrmUsersaId) Serialize() []byte { | ||||
| 	return (*(*[SizeofXfrmUsersaId]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
|  | ||||
| // struct xfrm_stats { | ||||
| //   __u32 replay_window; | ||||
| //   __u32 replay; | ||||
| //   __u32 integrity_failed; | ||||
| // }; | ||||
|  | ||||
| type XfrmStats struct { | ||||
| 	ReplayWindow    uint32 | ||||
| 	Replay          uint32 | ||||
| 	IntegrityFailed uint32 | ||||
| } | ||||
|  | ||||
| func (msg *XfrmStats) Len() int { | ||||
| 	return SizeofXfrmStats | ||||
| } | ||||
|  | ||||
| func DeserializeXfrmStats(b []byte) *XfrmStats { | ||||
| 	return (*XfrmStats)(unsafe.Pointer(&b[0:SizeofXfrmStats][0])) | ||||
| } | ||||
|  | ||||
| func (msg *XfrmStats) Serialize() []byte { | ||||
| 	return (*(*[SizeofXfrmStats]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
|  | ||||
| // struct xfrm_usersa_info { | ||||
| //   struct xfrm_selector    sel; | ||||
| //   struct xfrm_id      id; | ||||
| //   xfrm_address_t      saddr; | ||||
| //   struct xfrm_lifetime_cfg  lft; | ||||
| //   struct xfrm_lifetime_cur  curlft; | ||||
| //   struct xfrm_stats   stats; | ||||
| //   __u32       seq; | ||||
| //   __u32       reqid; | ||||
| //   __u16       family; | ||||
| //   __u8        mode;   /* XFRM_MODE_xxx */ | ||||
| //   __u8        replay_window; | ||||
| //   __u8        flags; | ||||
| // #define XFRM_STATE_NOECN  1 | ||||
| // #define XFRM_STATE_DECAP_DSCP 2 | ||||
| // #define XFRM_STATE_NOPMTUDISC 4 | ||||
| // #define XFRM_STATE_WILDRECV 8 | ||||
| // #define XFRM_STATE_ICMP   16 | ||||
| // #define XFRM_STATE_AF_UNSPEC  32 | ||||
| // #define XFRM_STATE_ALIGN4 64 | ||||
| // #define XFRM_STATE_ESN    128 | ||||
| // }; | ||||
| // | ||||
| // #define XFRM_SA_XFLAG_DONT_ENCAP_DSCP 1 | ||||
| // | ||||
|  | ||||
| type XfrmUsersaInfo struct { | ||||
| 	Sel          XfrmSelector | ||||
| 	Id           XfrmId | ||||
| 	Saddr        XfrmAddress | ||||
| 	Lft          XfrmLifetimeCfg | ||||
| 	Curlft       XfrmLifetimeCur | ||||
| 	Stats        XfrmStats | ||||
| 	Seq          uint32 | ||||
| 	Reqid        uint32 | ||||
| 	Family       uint16 | ||||
| 	Mode         uint8 | ||||
| 	ReplayWindow uint8 | ||||
| 	Flags        uint8 | ||||
| 	Pad          [7]byte | ||||
| } | ||||
|  | ||||
| func (msg *XfrmUsersaInfo) Len() int { | ||||
| 	return SizeofXfrmUsersaInfo | ||||
| } | ||||
|  | ||||
| func DeserializeXfrmUsersaInfo(b []byte) *XfrmUsersaInfo { | ||||
| 	return (*XfrmUsersaInfo)(unsafe.Pointer(&b[0:SizeofXfrmUsersaInfo][0])) | ||||
| } | ||||
|  | ||||
| func (msg *XfrmUsersaInfo) Serialize() []byte { | ||||
| 	return (*(*[SizeofXfrmUsersaInfo]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
|  | ||||
| // struct xfrm_algo { | ||||
| //   char    alg_name[64]; | ||||
| //   unsigned int  alg_key_len;    /* in bits */ | ||||
| //   char    alg_key[0]; | ||||
| // }; | ||||
|  | ||||
| type XfrmAlgo struct { | ||||
| 	AlgName   [64]byte | ||||
| 	AlgKeyLen uint32 | ||||
| 	AlgKey    []byte | ||||
| } | ||||
|  | ||||
| func (msg *XfrmAlgo) Len() int { | ||||
| 	return SizeofXfrmAlgo + int(msg.AlgKeyLen/8) | ||||
| } | ||||
|  | ||||
| func DeserializeXfrmAlgo(b []byte) *XfrmAlgo { | ||||
| 	ret := XfrmAlgo{} | ||||
| 	copy(ret.AlgName[:], b[0:64]) | ||||
| 	ret.AlgKeyLen = *(*uint32)(unsafe.Pointer(&b[64])) | ||||
| 	ret.AlgKey = b[68:ret.Len()] | ||||
| 	return &ret | ||||
| } | ||||
|  | ||||
| func (msg *XfrmAlgo) Serialize() []byte { | ||||
| 	b := make([]byte, msg.Len()) | ||||
| 	copy(b[0:64], msg.AlgName[:]) | ||||
| 	copy(b[64:68], (*(*[4]byte)(unsafe.Pointer(&msg.AlgKeyLen)))[:]) | ||||
| 	copy(b[68:msg.Len()], msg.AlgKey[:]) | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| // struct xfrm_algo_auth { | ||||
| //   char    alg_name[64]; | ||||
| //   unsigned int  alg_key_len;    /* in bits */ | ||||
| //   unsigned int  alg_trunc_len;  /* in bits */ | ||||
| //   char    alg_key[0]; | ||||
| // }; | ||||
|  | ||||
| type XfrmAlgoAuth struct { | ||||
| 	AlgName     [64]byte | ||||
| 	AlgKeyLen   uint32 | ||||
| 	AlgTruncLen uint32 | ||||
| 	AlgKey      []byte | ||||
| } | ||||
|  | ||||
| func (msg *XfrmAlgoAuth) Len() int { | ||||
| 	return SizeofXfrmAlgoAuth + int(msg.AlgKeyLen/8) | ||||
| } | ||||
|  | ||||
| func DeserializeXfrmAlgoAuth(b []byte) *XfrmAlgoAuth { | ||||
| 	ret := XfrmAlgoAuth{} | ||||
| 	copy(ret.AlgName[:], b[0:64]) | ||||
| 	ret.AlgKeyLen = *(*uint32)(unsafe.Pointer(&b[64])) | ||||
| 	ret.AlgTruncLen = *(*uint32)(unsafe.Pointer(&b[68])) | ||||
| 	ret.AlgKey = b[72:ret.Len()] | ||||
| 	return &ret | ||||
| } | ||||
|  | ||||
| func (msg *XfrmAlgoAuth) Serialize() []byte { | ||||
| 	b := make([]byte, msg.Len()) | ||||
| 	copy(b[0:64], msg.AlgName[:]) | ||||
| 	copy(b[64:68], (*(*[4]byte)(unsafe.Pointer(&msg.AlgKeyLen)))[:]) | ||||
| 	copy(b[68:72], (*(*[4]byte)(unsafe.Pointer(&msg.AlgTruncLen)))[:]) | ||||
| 	copy(b[72:msg.Len()], msg.AlgKey[:]) | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| // struct xfrm_algo_aead { | ||||
| //   char    alg_name[64]; | ||||
| //   unsigned int  alg_key_len;  /* in bits */ | ||||
| //   unsigned int  alg_icv_len;  /* in bits */ | ||||
| //   char    alg_key[0]; | ||||
| // } | ||||
|  | ||||
| // struct xfrm_encap_tmpl { | ||||
| //   __u16   encap_type; | ||||
| //   __be16    encap_sport; | ||||
| //   __be16    encap_dport; | ||||
| //   xfrm_address_t  encap_oa; | ||||
| // }; | ||||
|  | ||||
| type XfrmEncapTmpl struct { | ||||
| 	EncapType  uint16 | ||||
| 	EncapSport uint16 // big endian | ||||
| 	EncapDport uint16 // big endian | ||||
| 	Pad        [2]byte | ||||
| 	EncapOa    XfrmAddress | ||||
| } | ||||
|  | ||||
| func (msg *XfrmEncapTmpl) Len() int { | ||||
| 	return SizeofXfrmEncapTmpl | ||||
| } | ||||
|  | ||||
| func DeserializeXfrmEncapTmpl(b []byte) *XfrmEncapTmpl { | ||||
| 	return (*XfrmEncapTmpl)(unsafe.Pointer(&b[0:SizeofXfrmEncapTmpl][0])) | ||||
| } | ||||
|  | ||||
| func (msg *XfrmEncapTmpl) Serialize() []byte { | ||||
| 	return (*(*[SizeofXfrmEncapTmpl]byte)(unsafe.Pointer(msg)))[:] | ||||
| } | ||||
							
								
								
									
										53
									
								
								vendor/github.com/vishvananda/netlink/protinfo.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										53
									
								
								vendor/github.com/vishvananda/netlink/protinfo.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,53 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // Protinfo represents bridge flags from netlink. | ||||
| type Protinfo struct { | ||||
| 	Hairpin   bool | ||||
| 	Guard     bool | ||||
| 	FastLeave bool | ||||
| 	RootBlock bool | ||||
| 	Learning  bool | ||||
| 	Flood     bool | ||||
| } | ||||
|  | ||||
| // String returns a list of enabled flags | ||||
| func (prot *Protinfo) String() string { | ||||
| 	var boolStrings []string | ||||
| 	if prot.Hairpin { | ||||
| 		boolStrings = append(boolStrings, "Hairpin") | ||||
| 	} | ||||
| 	if prot.Guard { | ||||
| 		boolStrings = append(boolStrings, "Guard") | ||||
| 	} | ||||
| 	if prot.FastLeave { | ||||
| 		boolStrings = append(boolStrings, "FastLeave") | ||||
| 	} | ||||
| 	if prot.RootBlock { | ||||
| 		boolStrings = append(boolStrings, "RootBlock") | ||||
| 	} | ||||
| 	if prot.Learning { | ||||
| 		boolStrings = append(boolStrings, "Learning") | ||||
| 	} | ||||
| 	if prot.Flood { | ||||
| 		boolStrings = append(boolStrings, "Flood") | ||||
| 	} | ||||
| 	return strings.Join(boolStrings, " ") | ||||
| } | ||||
|  | ||||
| func boolToByte(x bool) []byte { | ||||
| 	if x { | ||||
| 		return []byte{1} | ||||
| 	} | ||||
| 	return []byte{0} | ||||
| } | ||||
|  | ||||
| func byteToBool(x byte) bool { | ||||
| 	if uint8(x) != 0 { | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
							
								
								
									
										60
									
								
								vendor/github.com/vishvananda/netlink/protinfo_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										60
									
								
								vendor/github.com/vishvananda/netlink/protinfo_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,60 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"syscall" | ||||
|  | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
|  | ||||
| func LinkGetProtinfo(link Link) (Protinfo, error) { | ||||
| 	base := link.Attrs() | ||||
| 	ensureIndex(base) | ||||
| 	var pi Protinfo | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_DUMP) | ||||
| 	msg := nl.NewIfInfomsg(syscall.AF_BRIDGE) | ||||
| 	req.AddData(msg) | ||||
| 	msgs, err := req.Execute(syscall.NETLINK_ROUTE, 0) | ||||
| 	if err != nil { | ||||
| 		return pi, err | ||||
| 	} | ||||
|  | ||||
| 	for _, m := range msgs { | ||||
| 		ans := nl.DeserializeIfInfomsg(m) | ||||
| 		if int(ans.Index) != base.Index { | ||||
| 			continue | ||||
| 		} | ||||
| 		attrs, err := nl.ParseRouteAttr(m[ans.Len():]) | ||||
| 		if err != nil { | ||||
| 			return pi, err | ||||
| 		} | ||||
| 		for _, attr := range attrs { | ||||
| 			if attr.Attr.Type != syscall.IFLA_PROTINFO|syscall.NLA_F_NESTED { | ||||
| 				continue | ||||
| 			} | ||||
| 			infos, err := nl.ParseRouteAttr(attr.Value) | ||||
| 			if err != nil { | ||||
| 				return pi, err | ||||
| 			} | ||||
| 			var pi Protinfo | ||||
| 			for _, info := range infos { | ||||
| 				switch info.Attr.Type { | ||||
| 				case nl.IFLA_BRPORT_MODE: | ||||
| 					pi.Hairpin = byteToBool(info.Value[0]) | ||||
| 				case nl.IFLA_BRPORT_GUARD: | ||||
| 					pi.Guard = byteToBool(info.Value[0]) | ||||
| 				case nl.IFLA_BRPORT_FAST_LEAVE: | ||||
| 					pi.FastLeave = byteToBool(info.Value[0]) | ||||
| 				case nl.IFLA_BRPORT_PROTECT: | ||||
| 					pi.RootBlock = byteToBool(info.Value[0]) | ||||
| 				case nl.IFLA_BRPORT_LEARNING: | ||||
| 					pi.Learning = byteToBool(info.Value[0]) | ||||
| 				case nl.IFLA_BRPORT_UNICAST_FLOOD: | ||||
| 					pi.Flood = byteToBool(info.Value[0]) | ||||
| 				} | ||||
| 			} | ||||
| 			return pi, nil | ||||
| 		} | ||||
| 	} | ||||
| 	return pi, fmt.Errorf("Device with index %d not found", base.Index) | ||||
| } | ||||
							
								
								
									
										290
									
								
								vendor/github.com/vishvananda/netlink/qdisc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										290
									
								
								vendor/github.com/vishvananda/netlink/qdisc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,290 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"math" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	HANDLE_NONE      = 0 | ||||
| 	HANDLE_INGRESS   = 0xFFFFFFF1 | ||||
| 	HANDLE_ROOT      = 0xFFFFFFFF | ||||
| 	PRIORITY_MAP_LEN = 16 | ||||
| ) | ||||
|  | ||||
| type Qdisc interface { | ||||
| 	Attrs() *QdiscAttrs | ||||
| 	Type() string | ||||
| } | ||||
|  | ||||
| // Qdisc represents a netlink qdisc. A qdisc is associated with a link, | ||||
| // has a handle, a parent and a refcnt. The root qdisc of a device should | ||||
| // have parent == HANDLE_ROOT. | ||||
| type QdiscAttrs struct { | ||||
| 	LinkIndex int | ||||
| 	Handle    uint32 | ||||
| 	Parent    uint32 | ||||
| 	Refcnt    uint32 // read only | ||||
| } | ||||
|  | ||||
| func (q QdiscAttrs) String() string { | ||||
| 	return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Refcnt: %s}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Refcnt) | ||||
| } | ||||
|  | ||||
| func MakeHandle(major, minor uint16) uint32 { | ||||
| 	return (uint32(major) << 16) | uint32(minor) | ||||
| } | ||||
|  | ||||
| func MajorMinor(handle uint32) (uint16, uint16) { | ||||
| 	return uint16((handle & 0xFFFF0000) >> 16), uint16(handle & 0x0000FFFFF) | ||||
| } | ||||
|  | ||||
| func HandleStr(handle uint32) string { | ||||
| 	switch handle { | ||||
| 	case HANDLE_NONE: | ||||
| 		return "none" | ||||
| 	case HANDLE_INGRESS: | ||||
| 		return "ingress" | ||||
| 	case HANDLE_ROOT: | ||||
| 		return "root" | ||||
| 	default: | ||||
| 		major, minor := MajorMinor(handle) | ||||
| 		return fmt.Sprintf("%x:%x", major, minor) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Percentage2u32(percentage float32) uint32 { | ||||
| 	// FIXME this is most likely not the best way to convert from % to uint32 | ||||
| 	if percentage == 100 { | ||||
| 		return math.MaxUint32 | ||||
| 	} | ||||
| 	return uint32(math.MaxUint32 * (percentage / 100)) | ||||
| } | ||||
|  | ||||
| // PfifoFast is the default qdisc created by the kernel if one has not | ||||
| // been defined for the interface | ||||
| type PfifoFast struct { | ||||
| 	QdiscAttrs | ||||
| 	Bands       uint8 | ||||
| 	PriorityMap [PRIORITY_MAP_LEN]uint8 | ||||
| } | ||||
|  | ||||
| func (qdisc *PfifoFast) Attrs() *QdiscAttrs { | ||||
| 	return &qdisc.QdiscAttrs | ||||
| } | ||||
|  | ||||
| func (qdisc *PfifoFast) Type() string { | ||||
| 	return "pfifo_fast" | ||||
| } | ||||
|  | ||||
| // Prio is a basic qdisc that works just like PfifoFast | ||||
| type Prio struct { | ||||
| 	QdiscAttrs | ||||
| 	Bands       uint8 | ||||
| 	PriorityMap [PRIORITY_MAP_LEN]uint8 | ||||
| } | ||||
|  | ||||
| func NewPrio(attrs QdiscAttrs) *Prio { | ||||
| 	return &Prio{ | ||||
| 		QdiscAttrs:  attrs, | ||||
| 		Bands:       3, | ||||
| 		PriorityMap: [PRIORITY_MAP_LEN]uint8{1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (qdisc *Prio) Attrs() *QdiscAttrs { | ||||
| 	return &qdisc.QdiscAttrs | ||||
| } | ||||
|  | ||||
| func (qdisc *Prio) Type() string { | ||||
| 	return "prio" | ||||
| } | ||||
|  | ||||
| // Htb is a classful qdisc that rate limits based on tokens | ||||
| type Htb struct { | ||||
| 	QdiscAttrs | ||||
| 	Version      uint32 | ||||
| 	Rate2Quantum uint32 | ||||
| 	Defcls       uint32 | ||||
| 	Debug        uint32 | ||||
| 	DirectPkts   uint32 | ||||
| } | ||||
|  | ||||
| func NewHtb(attrs QdiscAttrs) *Htb { | ||||
| 	return &Htb{ | ||||
| 		QdiscAttrs:   attrs, | ||||
| 		Version:      3, | ||||
| 		Defcls:       0, | ||||
| 		Rate2Quantum: 10, | ||||
| 		Debug:        0, | ||||
| 		DirectPkts:   0, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (qdisc *Htb) Attrs() *QdiscAttrs { | ||||
| 	return &qdisc.QdiscAttrs | ||||
| } | ||||
|  | ||||
| func (qdisc *Htb) Type() string { | ||||
| 	return "htb" | ||||
| } | ||||
|  | ||||
| // Netem is a classless qdisc that rate limits based on tokens | ||||
|  | ||||
| type NetemQdiscAttrs struct { | ||||
| 	Latency       uint32  // in us | ||||
| 	DelayCorr     float32 // in % | ||||
| 	Limit         uint32 | ||||
| 	Loss          float32 // in % | ||||
| 	LossCorr      float32 // in % | ||||
| 	Gap           uint32 | ||||
| 	Duplicate     float32 // in % | ||||
| 	DuplicateCorr float32 // in % | ||||
| 	Jitter        uint32  // in us | ||||
| 	ReorderProb   float32 // in % | ||||
| 	ReorderCorr   float32 // in % | ||||
| 	CorruptProb   float32 // in % | ||||
| 	CorruptCorr   float32 // in % | ||||
| } | ||||
|  | ||||
| func (q NetemQdiscAttrs) String() string { | ||||
| 	return fmt.Sprintf( | ||||
| 		"{Latency: %d, Limit: %d, Loss: %d, Gap: %d, Duplicate: %d, Jitter: %d}", | ||||
| 		q.Latency, q.Limit, q.Loss, q.Gap, q.Duplicate, q.Jitter, | ||||
| 	) | ||||
| } | ||||
|  | ||||
| type Netem struct { | ||||
| 	QdiscAttrs | ||||
| 	Latency       uint32 | ||||
| 	DelayCorr     uint32 | ||||
| 	Limit         uint32 | ||||
| 	Loss          uint32 | ||||
| 	LossCorr      uint32 | ||||
| 	Gap           uint32 | ||||
| 	Duplicate     uint32 | ||||
| 	DuplicateCorr uint32 | ||||
| 	Jitter        uint32 | ||||
| 	ReorderProb   uint32 | ||||
| 	ReorderCorr   uint32 | ||||
| 	CorruptProb   uint32 | ||||
| 	CorruptCorr   uint32 | ||||
| } | ||||
|  | ||||
| func NewNetem(attrs QdiscAttrs, nattrs NetemQdiscAttrs) *Netem { | ||||
| 	var limit uint32 = 1000 | ||||
| 	var loss_corr, delay_corr, duplicate_corr uint32 | ||||
| 	var reorder_prob, reorder_corr uint32 | ||||
| 	var corrupt_prob, corrupt_corr uint32 | ||||
|  | ||||
| 	latency := nattrs.Latency | ||||
| 	loss := Percentage2u32(nattrs.Loss) | ||||
| 	gap := nattrs.Gap | ||||
| 	duplicate := Percentage2u32(nattrs.Duplicate) | ||||
| 	jitter := nattrs.Jitter | ||||
|  | ||||
| 	// Correlation | ||||
| 	if latency > 0 && jitter > 0 { | ||||
| 		delay_corr = Percentage2u32(nattrs.DelayCorr) | ||||
| 	} | ||||
| 	if loss > 0 { | ||||
| 		loss_corr = Percentage2u32(nattrs.LossCorr) | ||||
| 	} | ||||
| 	if duplicate > 0 { | ||||
| 		duplicate_corr = Percentage2u32(nattrs.DuplicateCorr) | ||||
| 	} | ||||
| 	// FIXME should validate values(like loss/duplicate are percentages...) | ||||
| 	latency = time2Tick(latency) | ||||
|  | ||||
| 	if nattrs.Limit != 0 { | ||||
| 		limit = nattrs.Limit | ||||
| 	} | ||||
| 	// Jitter is only value if latency is > 0 | ||||
| 	if latency > 0 { | ||||
| 		jitter = time2Tick(jitter) | ||||
| 	} | ||||
|  | ||||
| 	reorder_prob = Percentage2u32(nattrs.ReorderProb) | ||||
| 	reorder_corr = Percentage2u32(nattrs.ReorderCorr) | ||||
|  | ||||
| 	if reorder_prob > 0 { | ||||
| 		// ERROR if lantency == 0 | ||||
| 		if gap == 0 { | ||||
| 			gap = 1 | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	corrupt_prob = Percentage2u32(nattrs.CorruptProb) | ||||
| 	corrupt_corr = Percentage2u32(nattrs.CorruptCorr) | ||||
|  | ||||
| 	return &Netem{ | ||||
| 		QdiscAttrs:    attrs, | ||||
| 		Latency:       latency, | ||||
| 		DelayCorr:     delay_corr, | ||||
| 		Limit:         limit, | ||||
| 		Loss:          loss, | ||||
| 		LossCorr:      loss_corr, | ||||
| 		Gap:           gap, | ||||
| 		Duplicate:     duplicate, | ||||
| 		DuplicateCorr: duplicate_corr, | ||||
| 		Jitter:        jitter, | ||||
| 		ReorderProb:   reorder_prob, | ||||
| 		ReorderCorr:   reorder_corr, | ||||
| 		CorruptProb:   corrupt_prob, | ||||
| 		CorruptCorr:   corrupt_corr, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (qdisc *Netem) Attrs() *QdiscAttrs { | ||||
| 	return &qdisc.QdiscAttrs | ||||
| } | ||||
|  | ||||
| func (qdisc *Netem) Type() string { | ||||
| 	return "netem" | ||||
| } | ||||
|  | ||||
| // Tbf is a classless qdisc that rate limits based on tokens | ||||
| type Tbf struct { | ||||
| 	QdiscAttrs | ||||
| 	// TODO: handle 64bit rate properly | ||||
| 	Rate   uint64 | ||||
| 	Limit  uint32 | ||||
| 	Buffer uint32 | ||||
| 	// TODO: handle other settings | ||||
| } | ||||
|  | ||||
| func (qdisc *Tbf) Attrs() *QdiscAttrs { | ||||
| 	return &qdisc.QdiscAttrs | ||||
| } | ||||
|  | ||||
| func (qdisc *Tbf) Type() string { | ||||
| 	return "tbf" | ||||
| } | ||||
|  | ||||
| // Ingress is a qdisc for adding ingress filters | ||||
| type Ingress struct { | ||||
| 	QdiscAttrs | ||||
| } | ||||
|  | ||||
| func (qdisc *Ingress) Attrs() *QdiscAttrs { | ||||
| 	return &qdisc.QdiscAttrs | ||||
| } | ||||
|  | ||||
| func (qdisc *Ingress) Type() string { | ||||
| 	return "ingress" | ||||
| } | ||||
|  | ||||
| // GenericQdisc qdiscs represent types that are not currently understood | ||||
| // by this netlink library. | ||||
| type GenericQdisc struct { | ||||
| 	QdiscAttrs | ||||
| 	QdiscType string | ||||
| } | ||||
|  | ||||
| func (qdisc *GenericQdisc) Attrs() *QdiscAttrs { | ||||
| 	return &qdisc.QdiscAttrs | ||||
| } | ||||
|  | ||||
| func (qdisc *GenericQdisc) Type() string { | ||||
| 	return qdisc.QdiscType | ||||
| } | ||||
							
								
								
									
										415
									
								
								vendor/github.com/vishvananda/netlink/qdisc_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										415
									
								
								vendor/github.com/vishvananda/netlink/qdisc_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,415 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"syscall" | ||||
|  | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
|  | ||||
| // QdiscDel will delete a qdisc from the system. | ||||
| // Equivalent to: `tc qdisc del $qdisc` | ||||
| func QdiscDel(qdisc Qdisc) error { | ||||
| 	return qdiscModify(syscall.RTM_DELQDISC, 0, qdisc) | ||||
| } | ||||
|  | ||||
| // QdiscChange will change a qdisc in place | ||||
| // Equivalent to: `tc qdisc change $qdisc` | ||||
| // The parent and handle MUST NOT be changed. | ||||
| func QdiscChange(qdisc Qdisc) error { | ||||
| 	return qdiscModify(syscall.RTM_NEWQDISC, 0, qdisc) | ||||
| } | ||||
|  | ||||
| // QdiscReplace will replace a qdisc to the system. | ||||
| // Equivalent to: `tc qdisc replace $qdisc` | ||||
| // The handle MUST change. | ||||
| func QdiscReplace(qdisc Qdisc) error { | ||||
| 	return qdiscModify( | ||||
| 		syscall.RTM_NEWQDISC, | ||||
| 		syscall.NLM_F_CREATE|syscall.NLM_F_REPLACE, | ||||
| 		qdisc) | ||||
| } | ||||
|  | ||||
| // QdiscAdd will add a qdisc to the system. | ||||
| // Equivalent to: `tc qdisc add $qdisc` | ||||
| func QdiscAdd(qdisc Qdisc) error { | ||||
| 	return qdiscModify( | ||||
| 		syscall.RTM_NEWQDISC, | ||||
| 		syscall.NLM_F_CREATE|syscall.NLM_F_EXCL, | ||||
| 		qdisc) | ||||
| } | ||||
|  | ||||
| func qdiscModify(cmd, flags int, qdisc Qdisc) error { | ||||
| 	req := nl.NewNetlinkRequest(cmd, flags|syscall.NLM_F_ACK) | ||||
| 	base := qdisc.Attrs() | ||||
| 	msg := &nl.TcMsg{ | ||||
| 		Family:  nl.FAMILY_ALL, | ||||
| 		Ifindex: int32(base.LinkIndex), | ||||
| 		Handle:  base.Handle, | ||||
| 		Parent:  base.Parent, | ||||
| 	} | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	// When deleting don't bother building the rest of the netlink payload | ||||
| 	if cmd != syscall.RTM_DELQDISC { | ||||
| 		if err := qdiscPayload(req, qdisc); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	_, err := req.Execute(syscall.NETLINK_ROUTE, 0) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error { | ||||
|  | ||||
| 	req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(qdisc.Type()))) | ||||
|  | ||||
| 	options := nl.NewRtAttr(nl.TCA_OPTIONS, nil) | ||||
| 	if prio, ok := qdisc.(*Prio); ok { | ||||
| 		tcmap := nl.TcPrioMap{ | ||||
| 			Bands:   int32(prio.Bands), | ||||
| 			Priomap: prio.PriorityMap, | ||||
| 		} | ||||
| 		options = nl.NewRtAttr(nl.TCA_OPTIONS, tcmap.Serialize()) | ||||
| 	} else if tbf, ok := qdisc.(*Tbf); ok { | ||||
| 		opt := nl.TcTbfQopt{} | ||||
| 		// TODO: handle rate > uint32 | ||||
| 		opt.Rate.Rate = uint32(tbf.Rate) | ||||
| 		opt.Limit = tbf.Limit | ||||
| 		opt.Buffer = tbf.Buffer | ||||
| 		nl.NewRtAttrChild(options, nl.TCA_TBF_PARMS, opt.Serialize()) | ||||
| 	} else if htb, ok := qdisc.(*Htb); ok { | ||||
| 		opt := nl.TcHtbGlob{} | ||||
| 		opt.Version = htb.Version | ||||
| 		opt.Rate2Quantum = htb.Rate2Quantum | ||||
| 		opt.Defcls = htb.Defcls | ||||
| 		// TODO: Handle Debug properly. For now default to 0 | ||||
| 		opt.Debug = htb.Debug | ||||
| 		opt.DirectPkts = htb.DirectPkts | ||||
| 		nl.NewRtAttrChild(options, nl.TCA_HTB_INIT, opt.Serialize()) | ||||
| 		// nl.NewRtAttrChild(options, nl.TCA_HTB_DIRECT_QLEN, opt.Serialize()) | ||||
| 	} else if netem, ok := qdisc.(*Netem); ok { | ||||
| 		opt := nl.TcNetemQopt{} | ||||
| 		opt.Latency = netem.Latency | ||||
| 		opt.Limit = netem.Limit | ||||
| 		opt.Loss = netem.Loss | ||||
| 		opt.Gap = netem.Gap | ||||
| 		opt.Duplicate = netem.Duplicate | ||||
| 		opt.Jitter = netem.Jitter | ||||
| 		options = nl.NewRtAttr(nl.TCA_OPTIONS, opt.Serialize()) | ||||
| 		// Correlation | ||||
| 		corr := nl.TcNetemCorr{} | ||||
| 		corr.DelayCorr = netem.DelayCorr | ||||
| 		corr.LossCorr = netem.LossCorr | ||||
| 		corr.DupCorr = netem.DuplicateCorr | ||||
|  | ||||
| 		if corr.DelayCorr > 0 || corr.LossCorr > 0 || corr.DupCorr > 0 { | ||||
| 			nl.NewRtAttrChild(options, nl.TCA_NETEM_CORR, corr.Serialize()) | ||||
| 		} | ||||
| 		// Corruption | ||||
| 		corruption := nl.TcNetemCorrupt{} | ||||
| 		corruption.Probability = netem.CorruptProb | ||||
| 		corruption.Correlation = netem.CorruptCorr | ||||
| 		if corruption.Probability > 0 { | ||||
| 			nl.NewRtAttrChild(options, nl.TCA_NETEM_CORRUPT, corruption.Serialize()) | ||||
| 		} | ||||
| 		// Reorder | ||||
| 		reorder := nl.TcNetemReorder{} | ||||
| 		reorder.Probability = netem.ReorderProb | ||||
| 		reorder.Correlation = netem.ReorderCorr | ||||
| 		if reorder.Probability > 0 { | ||||
| 			nl.NewRtAttrChild(options, nl.TCA_NETEM_REORDER, reorder.Serialize()) | ||||
| 		} | ||||
| 	} else if _, ok := qdisc.(*Ingress); ok { | ||||
| 		// ingress filters must use the proper handle | ||||
| 		if qdisc.Attrs().Parent != HANDLE_INGRESS { | ||||
| 			return fmt.Errorf("Ingress filters must set Parent to HANDLE_INGRESS") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	req.AddData(options) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // QdiscList gets a list of qdiscs in the system. | ||||
| // Equivalent to: `tc qdisc show`. | ||||
| // The list can be filtered by link. | ||||
| func QdiscList(link Link) ([]Qdisc, error) { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_GETQDISC, syscall.NLM_F_DUMP) | ||||
| 	index := int32(0) | ||||
| 	if link != nil { | ||||
| 		base := link.Attrs() | ||||
| 		ensureIndex(base) | ||||
| 		index = int32(base.Index) | ||||
| 	} | ||||
| 	msg := &nl.TcMsg{ | ||||
| 		Family:  nl.FAMILY_ALL, | ||||
| 		Ifindex: index, | ||||
| 	} | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWQDISC) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var res []Qdisc | ||||
| 	for _, m := range msgs { | ||||
| 		msg := nl.DeserializeTcMsg(m) | ||||
|  | ||||
| 		attrs, err := nl.ParseRouteAttr(m[msg.Len():]) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		// skip qdiscs from other interfaces | ||||
| 		if link != nil && msg.Ifindex != index { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		base := QdiscAttrs{ | ||||
| 			LinkIndex: int(msg.Ifindex), | ||||
| 			Handle:    msg.Handle, | ||||
| 			Parent:    msg.Parent, | ||||
| 			Refcnt:    msg.Info, | ||||
| 		} | ||||
| 		var qdisc Qdisc | ||||
| 		qdiscType := "" | ||||
| 		for _, attr := range attrs { | ||||
| 			switch attr.Attr.Type { | ||||
| 			case nl.TCA_KIND: | ||||
| 				qdiscType = string(attr.Value[:len(attr.Value)-1]) | ||||
| 				switch qdiscType { | ||||
| 				case "pfifo_fast": | ||||
| 					qdisc = &PfifoFast{} | ||||
| 				case "prio": | ||||
| 					qdisc = &Prio{} | ||||
| 				case "tbf": | ||||
| 					qdisc = &Tbf{} | ||||
| 				case "ingress": | ||||
| 					qdisc = &Ingress{} | ||||
| 				case "htb": | ||||
| 					qdisc = &Htb{} | ||||
| 				case "netem": | ||||
| 					qdisc = &Netem{} | ||||
| 				default: | ||||
| 					qdisc = &GenericQdisc{QdiscType: qdiscType} | ||||
| 				} | ||||
| 			case nl.TCA_OPTIONS: | ||||
| 				switch qdiscType { | ||||
| 				case "pfifo_fast": | ||||
| 					// pfifo returns TcPrioMap directly without wrapping it in rtattr | ||||
| 					if err := parsePfifoFastData(qdisc, attr.Value); err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 				case "prio": | ||||
| 					// prio returns TcPrioMap directly without wrapping it in rtattr | ||||
| 					if err := parsePrioData(qdisc, attr.Value); err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 				case "tbf": | ||||
| 					data, err := nl.ParseRouteAttr(attr.Value) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 					if err := parseTbfData(qdisc, data); err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 				case "htb": | ||||
| 					data, err := nl.ParseRouteAttr(attr.Value) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 					if err := parseHtbData(qdisc, data); err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 				case "netem": | ||||
| 					if err := parseNetemData(qdisc, attr.Value); err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
|  | ||||
| 					// no options for ingress | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		*qdisc.Attrs() = base | ||||
| 		res = append(res, qdisc) | ||||
| 	} | ||||
|  | ||||
| 	return res, nil | ||||
| } | ||||
|  | ||||
| func parsePfifoFastData(qdisc Qdisc, value []byte) error { | ||||
| 	pfifo := qdisc.(*PfifoFast) | ||||
| 	tcmap := nl.DeserializeTcPrioMap(value) | ||||
| 	pfifo.PriorityMap = tcmap.Priomap | ||||
| 	pfifo.Bands = uint8(tcmap.Bands) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func parsePrioData(qdisc Qdisc, value []byte) error { | ||||
| 	prio := qdisc.(*Prio) | ||||
| 	tcmap := nl.DeserializeTcPrioMap(value) | ||||
| 	prio.PriorityMap = tcmap.Priomap | ||||
| 	prio.Bands = uint8(tcmap.Bands) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func parseHtbData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error { | ||||
| 	native = nl.NativeEndian() | ||||
| 	htb := qdisc.(*Htb) | ||||
| 	for _, datum := range data { | ||||
| 		switch datum.Attr.Type { | ||||
| 		case nl.TCA_HTB_INIT: | ||||
| 			opt := nl.DeserializeTcHtbGlob(datum.Value) | ||||
| 			htb.Version = opt.Version | ||||
| 			htb.Rate2Quantum = opt.Rate2Quantum | ||||
| 			htb.Defcls = opt.Defcls | ||||
| 			htb.Debug = opt.Debug | ||||
| 			htb.DirectPkts = opt.DirectPkts | ||||
| 		case nl.TCA_HTB_DIRECT_QLEN: | ||||
| 			// TODO | ||||
| 			//htb.DirectQlen = native.uint32(datum.Value) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func parseNetemData(qdisc Qdisc, value []byte) error { | ||||
| 	netem := qdisc.(*Netem) | ||||
| 	opt := nl.DeserializeTcNetemQopt(value) | ||||
| 	netem.Latency = opt.Latency | ||||
| 	netem.Limit = opt.Limit | ||||
| 	netem.Loss = opt.Loss | ||||
| 	netem.Gap = opt.Gap | ||||
| 	netem.Duplicate = opt.Duplicate | ||||
| 	netem.Jitter = opt.Jitter | ||||
| 	data, err := nl.ParseRouteAttr(value[nl.SizeofTcNetemQopt:]) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	for _, datum := range data { | ||||
| 		switch datum.Attr.Type { | ||||
| 		case nl.TCA_NETEM_CORR: | ||||
| 			opt := nl.DeserializeTcNetemCorr(datum.Value) | ||||
| 			netem.DelayCorr = opt.DelayCorr | ||||
| 			netem.LossCorr = opt.LossCorr | ||||
| 			netem.DuplicateCorr = opt.DupCorr | ||||
| 		case nl.TCA_NETEM_CORRUPT: | ||||
| 			opt := nl.DeserializeTcNetemCorrupt(datum.Value) | ||||
| 			netem.CorruptProb = opt.Probability | ||||
| 			netem.CorruptCorr = opt.Correlation | ||||
| 		case nl.TCA_NETEM_REORDER: | ||||
| 			opt := nl.DeserializeTcNetemReorder(datum.Value) | ||||
| 			netem.ReorderProb = opt.Probability | ||||
| 			netem.ReorderCorr = opt.Correlation | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func parseTbfData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error { | ||||
| 	native = nl.NativeEndian() | ||||
| 	tbf := qdisc.(*Tbf) | ||||
| 	for _, datum := range data { | ||||
| 		switch datum.Attr.Type { | ||||
| 		case nl.TCA_TBF_PARMS: | ||||
| 			opt := nl.DeserializeTcTbfQopt(datum.Value) | ||||
| 			tbf.Rate = uint64(opt.Rate.Rate) | ||||
| 			tbf.Limit = opt.Limit | ||||
| 			tbf.Buffer = opt.Buffer | ||||
| 		case nl.TCA_TBF_RATE64: | ||||
| 			tbf.Rate = native.Uint64(datum.Value[0:4]) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	TIME_UNITS_PER_SEC = 1000000 | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	tickInUsec  float64 = 0.0 | ||||
| 	clockFactor float64 = 0.0 | ||||
| 	hz          float64 = 0.0 | ||||
| ) | ||||
|  | ||||
| func initClock() { | ||||
| 	data, err := ioutil.ReadFile("/proc/net/psched") | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	parts := strings.Split(strings.TrimSpace(string(data)), " ") | ||||
| 	if len(parts) < 3 { | ||||
| 		return | ||||
| 	} | ||||
| 	var vals [3]uint64 | ||||
| 	for i := range vals { | ||||
| 		val, err := strconv.ParseUint(parts[i], 16, 32) | ||||
| 		if err != nil { | ||||
| 			return | ||||
| 		} | ||||
| 		vals[i] = val | ||||
| 	} | ||||
| 	// compatibility | ||||
| 	if vals[2] == 1000000000 { | ||||
| 		vals[0] = vals[1] | ||||
| 	} | ||||
| 	clockFactor = float64(vals[2]) / TIME_UNITS_PER_SEC | ||||
| 	tickInUsec = float64(vals[0]) / float64(vals[1]) * clockFactor | ||||
| 	hz = float64(vals[0]) | ||||
| } | ||||
|  | ||||
| func TickInUsec() float64 { | ||||
| 	if tickInUsec == 0.0 { | ||||
| 		initClock() | ||||
| 	} | ||||
| 	return tickInUsec | ||||
| } | ||||
|  | ||||
| func ClockFactor() float64 { | ||||
| 	if clockFactor == 0.0 { | ||||
| 		initClock() | ||||
| 	} | ||||
| 	return clockFactor | ||||
| } | ||||
|  | ||||
| func Hz() float64 { | ||||
| 	if hz == 0.0 { | ||||
| 		initClock() | ||||
| 	} | ||||
| 	return hz | ||||
| } | ||||
|  | ||||
| func time2Tick(time uint32) uint32 { | ||||
| 	return uint32(float64(time) * TickInUsec()) | ||||
| } | ||||
|  | ||||
| func tick2Time(tick uint32) uint32 { | ||||
| 	return uint32(float64(tick) / TickInUsec()) | ||||
| } | ||||
|  | ||||
| func time2Ktime(time uint32) uint32 { | ||||
| 	return uint32(float64(time) * ClockFactor()) | ||||
| } | ||||
|  | ||||
| func ktime2Time(ktime uint32) uint32 { | ||||
| 	return uint32(float64(ktime) / ClockFactor()) | ||||
| } | ||||
|  | ||||
| func burst(rate uint64, buffer uint32) uint32 { | ||||
| 	return uint32(float64(rate) * float64(tick2Time(buffer)) / TIME_UNITS_PER_SEC) | ||||
| } | ||||
|  | ||||
| func latency(rate uint64, limit, buffer uint32) float64 { | ||||
| 	return TIME_UNITS_PER_SEC*(float64(limit)/float64(rate)) - float64(tick2Time(buffer)) | ||||
| } | ||||
|  | ||||
| func Xmittime(rate uint64, size uint32) float64 { | ||||
| 	return TickInUsec() * TIME_UNITS_PER_SEC * (float64(size) / float64(rate)) | ||||
| } | ||||
							
								
								
									
										80
									
								
								vendor/github.com/vishvananda/netlink/route.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										80
									
								
								vendor/github.com/vishvananda/netlink/route.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,80 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"syscall" | ||||
| ) | ||||
|  | ||||
| // Scope is an enum representing a route scope. | ||||
| type Scope uint8 | ||||
|  | ||||
| const ( | ||||
| 	SCOPE_UNIVERSE Scope = syscall.RT_SCOPE_UNIVERSE | ||||
| 	SCOPE_SITE     Scope = syscall.RT_SCOPE_SITE | ||||
| 	SCOPE_LINK     Scope = syscall.RT_SCOPE_LINK | ||||
| 	SCOPE_HOST     Scope = syscall.RT_SCOPE_HOST | ||||
| 	SCOPE_NOWHERE  Scope = syscall.RT_SCOPE_NOWHERE | ||||
| ) | ||||
|  | ||||
| type NextHopFlag int | ||||
|  | ||||
| const ( | ||||
| 	FLAG_ONLINK    NextHopFlag = syscall.RTNH_F_ONLINK | ||||
| 	FLAG_PERVASIVE NextHopFlag = syscall.RTNH_F_PERVASIVE | ||||
| ) | ||||
|  | ||||
| // Route represents a netlink route. | ||||
| type Route struct { | ||||
| 	LinkIndex  int | ||||
| 	ILinkIndex int | ||||
| 	Scope      Scope | ||||
| 	Dst        *net.IPNet | ||||
| 	Src        net.IP | ||||
| 	Gw         net.IP | ||||
| 	Protocol   int | ||||
| 	Priority   int | ||||
| 	Table      int | ||||
| 	Type       int | ||||
| 	Tos        int | ||||
| 	Flags      int | ||||
| } | ||||
|  | ||||
| func (r Route) String() string { | ||||
| 	return fmt.Sprintf("{Ifindex: %d Dst: %s Src: %s Gw: %s Flags: %s}", r.LinkIndex, r.Dst, | ||||
| 		r.Src, r.Gw, r.ListFlags()) | ||||
| } | ||||
|  | ||||
| func (r *Route) SetFlag(flag NextHopFlag) { | ||||
| 	r.Flags |= int(flag) | ||||
| } | ||||
|  | ||||
| func (r *Route) ClearFlag(flag NextHopFlag) { | ||||
| 	r.Flags &^= int(flag) | ||||
| } | ||||
|  | ||||
| type flagString struct { | ||||
| 	f NextHopFlag | ||||
| 	s string | ||||
| } | ||||
|  | ||||
| var testFlags = []flagString{ | ||||
| 	flagString{f: FLAG_ONLINK, s: "onlink"}, | ||||
| 	flagString{f: FLAG_PERVASIVE, s: "pervasive"}, | ||||
| } | ||||
|  | ||||
| func (r *Route) ListFlags() []string { | ||||
| 	var flags []string | ||||
| 	for _, tf := range testFlags { | ||||
| 		if r.Flags&int(tf.f) != 0 { | ||||
| 			flags = append(flags, tf.s) | ||||
| 		} | ||||
| 	} | ||||
| 	return flags | ||||
| } | ||||
|  | ||||
| // RouteUpdate is sent when a route changes - type is RTM_NEWROUTE or RTM_DELROUTE | ||||
| type RouteUpdate struct { | ||||
| 	Type uint16 | ||||
| 	Route | ||||
| } | ||||
							
								
								
									
										327
									
								
								vendor/github.com/vishvananda/netlink/route_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										327
									
								
								vendor/github.com/vishvananda/netlink/route_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,327 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"syscall" | ||||
|  | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
|  | ||||
| // RtAttr is shared so it is in netlink_linux.go | ||||
|  | ||||
| const ( | ||||
| 	RT_FILTER_PROTOCOL uint64 = 1 << (1 + iota) | ||||
| 	RT_FILTER_SCOPE | ||||
| 	RT_FILTER_TYPE | ||||
| 	RT_FILTER_TOS | ||||
| 	RT_FILTER_IIF | ||||
| 	RT_FILTER_OIF | ||||
| 	RT_FILTER_DST | ||||
| 	RT_FILTER_SRC | ||||
| 	RT_FILTER_GW | ||||
| 	RT_FILTER_TABLE | ||||
| ) | ||||
|  | ||||
| // RouteAdd will add a route to the system. | ||||
| // Equivalent to: `ip route add $route` | ||||
| func RouteAdd(route *Route) error { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_NEWROUTE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) | ||||
| 	return routeHandle(route, req, nl.NewRtMsg()) | ||||
| } | ||||
|  | ||||
| // RouteDel will delete a route from the system. | ||||
| // Equivalent to: `ip route del $route` | ||||
| func RouteDel(route *Route) error { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_DELROUTE, syscall.NLM_F_ACK) | ||||
| 	return routeHandle(route, req, nl.NewRtDelMsg()) | ||||
| } | ||||
|  | ||||
| func routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg) error { | ||||
| 	if (route.Dst == nil || route.Dst.IP == nil) && route.Src == nil && route.Gw == nil { | ||||
| 		return fmt.Errorf("one of Dst.IP, Src, or Gw must not be nil") | ||||
| 	} | ||||
|  | ||||
| 	family := -1 | ||||
| 	var rtAttrs []*nl.RtAttr | ||||
|  | ||||
| 	if route.Dst != nil && route.Dst.IP != nil { | ||||
| 		dstLen, _ := route.Dst.Mask.Size() | ||||
| 		msg.Dst_len = uint8(dstLen) | ||||
| 		dstFamily := nl.GetIPFamily(route.Dst.IP) | ||||
| 		family = dstFamily | ||||
| 		var dstData []byte | ||||
| 		if dstFamily == FAMILY_V4 { | ||||
| 			dstData = route.Dst.IP.To4() | ||||
| 		} else { | ||||
| 			dstData = route.Dst.IP.To16() | ||||
| 		} | ||||
| 		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_DST, dstData)) | ||||
| 	} | ||||
|  | ||||
| 	if route.Src != nil { | ||||
| 		srcFamily := nl.GetIPFamily(route.Src) | ||||
| 		if family != -1 && family != srcFamily { | ||||
| 			return fmt.Errorf("source and destination ip are not the same IP family") | ||||
| 		} | ||||
| 		family = srcFamily | ||||
| 		var srcData []byte | ||||
| 		if srcFamily == FAMILY_V4 { | ||||
| 			srcData = route.Src.To4() | ||||
| 		} else { | ||||
| 			srcData = route.Src.To16() | ||||
| 		} | ||||
| 		// The commonly used src ip for routes is actually PREFSRC | ||||
| 		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_PREFSRC, srcData)) | ||||
| 	} | ||||
|  | ||||
| 	if route.Gw != nil { | ||||
| 		gwFamily := nl.GetIPFamily(route.Gw) | ||||
| 		if family != -1 && family != gwFamily { | ||||
| 			return fmt.Errorf("gateway, source, and destination ip are not the same IP family") | ||||
| 		} | ||||
| 		family = gwFamily | ||||
| 		var gwData []byte | ||||
| 		if gwFamily == FAMILY_V4 { | ||||
| 			gwData = route.Gw.To4() | ||||
| 		} else { | ||||
| 			gwData = route.Gw.To16() | ||||
| 		} | ||||
| 		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_GATEWAY, gwData)) | ||||
| 	} | ||||
|  | ||||
| 	if route.Table > 0 { | ||||
| 		if route.Table >= 256 { | ||||
| 			msg.Table = syscall.RT_TABLE_UNSPEC | ||||
| 			b := make([]byte, 4) | ||||
| 			native.PutUint32(b, uint32(route.Table)) | ||||
| 			rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_TABLE, b)) | ||||
| 		} else { | ||||
| 			msg.Table = uint8(route.Table) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if route.Priority > 0 { | ||||
| 		b := make([]byte, 4) | ||||
| 		native.PutUint32(b, uint32(route.Priority)) | ||||
| 		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_PRIORITY, b)) | ||||
| 	} | ||||
| 	if route.Tos > 0 { | ||||
| 		msg.Tos = uint8(route.Tos) | ||||
| 	} | ||||
| 	if route.Protocol > 0 { | ||||
| 		msg.Protocol = uint8(route.Protocol) | ||||
| 	} | ||||
| 	if route.Type > 0 { | ||||
| 		msg.Type = uint8(route.Type) | ||||
| 	} | ||||
|  | ||||
| 	msg.Scope = uint8(route.Scope) | ||||
| 	msg.Family = uint8(family) | ||||
| 	req.AddData(msg) | ||||
| 	for _, attr := range rtAttrs { | ||||
| 		req.AddData(attr) | ||||
| 	} | ||||
|  | ||||
| 	var ( | ||||
| 		b      = make([]byte, 4) | ||||
| 		native = nl.NativeEndian() | ||||
| 	) | ||||
| 	native.PutUint32(b, uint32(route.LinkIndex)) | ||||
|  | ||||
| 	req.AddData(nl.NewRtAttr(syscall.RTA_OIF, b)) | ||||
|  | ||||
| 	_, err := req.Execute(syscall.NETLINK_ROUTE, 0) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // RouteList gets a list of routes in the system. | ||||
| // Equivalent to: `ip route show`. | ||||
| // The list can be filtered by link and ip family. | ||||
| func RouteList(link Link, family int) ([]Route, error) { | ||||
| 	var routeFilter *Route | ||||
| 	if link != nil { | ||||
| 		routeFilter = &Route{ | ||||
| 			LinkIndex: link.Attrs().Index, | ||||
| 		} | ||||
| 	} | ||||
| 	return RouteListFiltered(family, routeFilter, RT_FILTER_OIF) | ||||
| } | ||||
|  | ||||
| // RouteListFiltered gets a list of routes in the system filtered with specified rules. | ||||
| // All rules must be defined in RouteFilter struct | ||||
| func RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_GETROUTE, syscall.NLM_F_DUMP) | ||||
| 	infmsg := nl.NewIfInfomsg(family) | ||||
| 	req.AddData(infmsg) | ||||
|  | ||||
| 	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWROUTE) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var res []Route | ||||
| 	for _, m := range msgs { | ||||
| 		msg := nl.DeserializeRtMsg(m) | ||||
| 		if msg.Flags&syscall.RTM_F_CLONED != 0 { | ||||
| 			// Ignore cloned routes | ||||
| 			continue | ||||
| 		} | ||||
| 		if msg.Table != syscall.RT_TABLE_MAIN { | ||||
| 			if filter == nil || filter != nil && filterMask&RT_FILTER_TABLE == 0 { | ||||
| 				// Ignore non-main tables | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
| 		route, err := deserializeRoute(m) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		if filter != nil { | ||||
| 			switch { | ||||
| 			case filterMask&RT_FILTER_TABLE != 0 && route.Table != filter.Table: | ||||
| 				continue | ||||
| 			case filterMask&RT_FILTER_PROTOCOL != 0 && route.Protocol != filter.Protocol: | ||||
| 				continue | ||||
| 			case filterMask&RT_FILTER_SCOPE != 0 && route.Scope != filter.Scope: | ||||
| 				continue | ||||
| 			case filterMask&RT_FILTER_TYPE != 0 && route.Type != filter.Type: | ||||
| 				continue | ||||
| 			case filterMask&RT_FILTER_TOS != 0 && route.Tos != filter.Tos: | ||||
| 				continue | ||||
| 			case filterMask&RT_FILTER_OIF != 0 && route.LinkIndex != filter.LinkIndex: | ||||
| 				continue | ||||
| 			case filterMask&RT_FILTER_IIF != 0 && route.ILinkIndex != filter.ILinkIndex: | ||||
| 				continue | ||||
| 			case filterMask&RT_FILTER_GW != 0 && !route.Gw.Equal(filter.Gw): | ||||
| 				continue | ||||
| 			case filterMask&RT_FILTER_SRC != 0 && !route.Src.Equal(filter.Src): | ||||
| 				continue | ||||
| 			case filterMask&RT_FILTER_DST != 0 && filter.Dst != nil: | ||||
| 				if route.Dst == nil { | ||||
| 					continue | ||||
| 				} | ||||
| 				aMaskLen, aMaskBits := route.Dst.Mask.Size() | ||||
| 				bMaskLen, bMaskBits := filter.Dst.Mask.Size() | ||||
| 				if !(route.Dst.IP.Equal(filter.Dst.IP) && aMaskLen == bMaskLen && aMaskBits == bMaskBits) { | ||||
| 					continue | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		res = append(res, route) | ||||
| 	} | ||||
| 	return res, nil | ||||
| } | ||||
|  | ||||
| // deserializeRoute decodes a binary netlink message into a Route struct | ||||
| func deserializeRoute(m []byte) (Route, error) { | ||||
| 	msg := nl.DeserializeRtMsg(m) | ||||
| 	attrs, err := nl.ParseRouteAttr(m[msg.Len():]) | ||||
| 	if err != nil { | ||||
| 		return Route{}, err | ||||
| 	} | ||||
| 	route := Route{ | ||||
| 		Scope:    Scope(msg.Scope), | ||||
| 		Protocol: int(msg.Protocol), | ||||
| 		Table:    int(msg.Table), | ||||
| 		Type:     int(msg.Type), | ||||
| 		Tos:      int(msg.Tos), | ||||
| 		Flags:    int(msg.Flags), | ||||
| 	} | ||||
|  | ||||
| 	native := nl.NativeEndian() | ||||
| 	for _, attr := range attrs { | ||||
| 		switch attr.Attr.Type { | ||||
| 		case syscall.RTA_GATEWAY: | ||||
| 			route.Gw = net.IP(attr.Value) | ||||
| 		case syscall.RTA_PREFSRC: | ||||
| 			route.Src = net.IP(attr.Value) | ||||
| 		case syscall.RTA_DST: | ||||
| 			route.Dst = &net.IPNet{ | ||||
| 				IP:   attr.Value, | ||||
| 				Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)), | ||||
| 			} | ||||
| 		case syscall.RTA_OIF: | ||||
| 			route.LinkIndex = int(native.Uint32(attr.Value[0:4])) | ||||
| 		case syscall.RTA_IIF: | ||||
| 			route.ILinkIndex = int(native.Uint32(attr.Value[0:4])) | ||||
| 		case syscall.RTA_PRIORITY: | ||||
| 			route.Priority = int(native.Uint32(attr.Value[0:4])) | ||||
| 		case syscall.RTA_TABLE: | ||||
| 			route.Table = int(native.Uint32(attr.Value[0:4])) | ||||
| 		} | ||||
| 	} | ||||
| 	return route, nil | ||||
| } | ||||
|  | ||||
| // RouteGet gets a route to a specific destination from the host system. | ||||
| // Equivalent to: 'ip route get'. | ||||
| func RouteGet(destination net.IP) ([]Route, error) { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_GETROUTE, syscall.NLM_F_REQUEST) | ||||
| 	family := nl.GetIPFamily(destination) | ||||
| 	var destinationData []byte | ||||
| 	var bitlen uint8 | ||||
| 	if family == FAMILY_V4 { | ||||
| 		destinationData = destination.To4() | ||||
| 		bitlen = 32 | ||||
| 	} else { | ||||
| 		destinationData = destination.To16() | ||||
| 		bitlen = 128 | ||||
| 	} | ||||
| 	msg := &nl.RtMsg{} | ||||
| 	msg.Family = uint8(family) | ||||
| 	msg.Dst_len = bitlen | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	rtaDst := nl.NewRtAttr(syscall.RTA_DST, destinationData) | ||||
| 	req.AddData(rtaDst) | ||||
|  | ||||
| 	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWROUTE) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var res []Route | ||||
| 	for _, m := range msgs { | ||||
| 		route, err := deserializeRoute(m) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		res = append(res, route) | ||||
| 	} | ||||
| 	return res, nil | ||||
|  | ||||
| } | ||||
|  | ||||
| // RouteSubscribe takes a chan down which notifications will be sent | ||||
| // when routes are added or deleted. Close the 'done' chan to stop subscription. | ||||
| func RouteSubscribe(ch chan<- RouteUpdate, done <-chan struct{}) error { | ||||
| 	s, err := nl.Subscribe(syscall.NETLINK_ROUTE, syscall.RTNLGRP_IPV4_ROUTE, syscall.RTNLGRP_IPV6_ROUTE) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if done != nil { | ||||
| 		go func() { | ||||
| 			<-done | ||||
| 			s.Close() | ||||
| 		}() | ||||
| 	} | ||||
| 	go func() { | ||||
| 		defer close(ch) | ||||
| 		for { | ||||
| 			msgs, err := s.Receive() | ||||
| 			if err != nil { | ||||
| 				return | ||||
| 			} | ||||
| 			for _, m := range msgs { | ||||
| 				route, err := deserializeRoute(m.Data) | ||||
| 				if err != nil { | ||||
| 					return | ||||
| 				} | ||||
| 				ch <- RouteUpdate{Type: m.Header.Type, Route: route} | ||||
| 			} | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										43
									
								
								vendor/github.com/vishvananda/netlink/rule.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								vendor/github.com/vishvananda/netlink/rule.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,43 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
|  | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
|  | ||||
| // Rule represents a netlink rule. | ||||
| type Rule struct { | ||||
| 	*nl.RtMsg | ||||
| 	Priority          int | ||||
| 	Table             int | ||||
| 	Mark              int | ||||
| 	Mask              int | ||||
| 	TunID             uint | ||||
| 	Goto              int | ||||
| 	Src               *net.IPNet | ||||
| 	Dst               *net.IPNet | ||||
| 	Flow              int | ||||
| 	IifName           string | ||||
| 	OifName           string | ||||
| 	SuppressIfgroup   int | ||||
| 	SuppressPrefixlen int | ||||
| } | ||||
|  | ||||
| func (r Rule) String() string { | ||||
| 	return fmt.Sprintf("ip rule %d: from %s table %d", r.Priority, r.Src, r.Table) | ||||
| } | ||||
|  | ||||
| // NewRule return empty rules. | ||||
| func NewRule() *Rule { | ||||
| 	return &Rule{ | ||||
| 		SuppressIfgroup:   -1, | ||||
| 		SuppressPrefixlen: -1, | ||||
| 		Priority:          -1, | ||||
| 		Mark:              -1, | ||||
| 		Mask:              -1, | ||||
| 		Goto:              -1, | ||||
| 		Flow:              -1, | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										198
									
								
								vendor/github.com/vishvananda/netlink/rule_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										198
									
								
								vendor/github.com/vishvananda/netlink/rule_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,198 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"syscall" | ||||
|  | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
|  | ||||
| // RuleAdd adds a rule to the system. | ||||
| // Equivalent to: ip rule add | ||||
| func RuleAdd(rule *Rule) error { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_NEWRULE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) | ||||
| 	return ruleHandle(rule, req) | ||||
| } | ||||
|  | ||||
| // RuleDel deletes a rule from the system. | ||||
| // Equivalent to: ip rule del | ||||
| func RuleDel(rule *Rule) error { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_DELRULE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) | ||||
| 	return ruleHandle(rule, req) | ||||
| } | ||||
|  | ||||
| func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error { | ||||
| 	msg := nl.NewRtMsg() | ||||
| 	msg.Family = syscall.AF_INET | ||||
| 	var dstFamily uint8 | ||||
|  | ||||
| 	var rtAttrs []*nl.RtAttr | ||||
| 	if rule.Dst != nil && rule.Dst.IP != nil { | ||||
| 		dstLen, _ := rule.Dst.Mask.Size() | ||||
| 		msg.Dst_len = uint8(dstLen) | ||||
| 		msg.Family = uint8(nl.GetIPFamily(rule.Dst.IP)) | ||||
| 		dstFamily = msg.Family | ||||
| 		var dstData []byte | ||||
| 		if msg.Family == syscall.AF_INET { | ||||
| 			dstData = rule.Dst.IP.To4() | ||||
| 		} else { | ||||
| 			dstData = rule.Dst.IP.To16() | ||||
| 		} | ||||
| 		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_DST, dstData)) | ||||
| 	} | ||||
|  | ||||
| 	if rule.Src != nil && rule.Src.IP != nil { | ||||
| 		msg.Family = uint8(nl.GetIPFamily(rule.Src.IP)) | ||||
| 		if dstFamily != 0 && dstFamily != msg.Family { | ||||
| 			return fmt.Errorf("source and destination ip are not the same IP family") | ||||
| 		} | ||||
| 		srcLen, _ := rule.Src.Mask.Size() | ||||
| 		msg.Src_len = uint8(srcLen) | ||||
| 		var srcData []byte | ||||
| 		if msg.Family == syscall.AF_INET { | ||||
| 			srcData = rule.Src.IP.To4() | ||||
| 		} else { | ||||
| 			srcData = rule.Src.IP.To16() | ||||
| 		} | ||||
| 		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_SRC, srcData)) | ||||
| 	} | ||||
|  | ||||
| 	if rule.Table >= 0 { | ||||
| 		msg.Table = uint8(rule.Table) | ||||
| 		if rule.Table >= 256 { | ||||
| 			msg.Table = syscall.RT_TABLE_UNSPEC | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	req.AddData(msg) | ||||
| 	for i := range rtAttrs { | ||||
| 		req.AddData(rtAttrs[i]) | ||||
| 	} | ||||
|  | ||||
| 	var ( | ||||
| 		b      = make([]byte, 4) | ||||
| 		native = nl.NativeEndian() | ||||
| 	) | ||||
|  | ||||
| 	if rule.Priority >= 0 { | ||||
| 		native.PutUint32(b, uint32(rule.Priority)) | ||||
| 		req.AddData(nl.NewRtAttr(nl.FRA_PRIORITY, b)) | ||||
| 	} | ||||
| 	if rule.Mark >= 0 { | ||||
| 		native.PutUint32(b, uint32(rule.Mark)) | ||||
| 		req.AddData(nl.NewRtAttr(nl.FRA_FWMARK, b)) | ||||
| 	} | ||||
| 	if rule.Mask >= 0 { | ||||
| 		native.PutUint32(b, uint32(rule.Mask)) | ||||
| 		req.AddData(nl.NewRtAttr(nl.FRA_FWMASK, b)) | ||||
| 	} | ||||
| 	if rule.Flow >= 0 { | ||||
| 		native.PutUint32(b, uint32(rule.Flow)) | ||||
| 		req.AddData(nl.NewRtAttr(nl.FRA_FLOW, b)) | ||||
| 	} | ||||
| 	if rule.TunID > 0 { | ||||
| 		native.PutUint32(b, uint32(rule.TunID)) | ||||
| 		req.AddData(nl.NewRtAttr(nl.FRA_TUN_ID, b)) | ||||
| 	} | ||||
| 	if rule.Table >= 256 { | ||||
| 		native.PutUint32(b, uint32(rule.Table)) | ||||
| 		req.AddData(nl.NewRtAttr(nl.FRA_TABLE, b)) | ||||
| 	} | ||||
| 	if msg.Table > 0 { | ||||
| 		if rule.SuppressPrefixlen >= 0 { | ||||
| 			native.PutUint32(b, uint32(rule.SuppressPrefixlen)) | ||||
| 			req.AddData(nl.NewRtAttr(nl.FRA_SUPPRESS_PREFIXLEN, b)) | ||||
| 		} | ||||
| 		if rule.SuppressIfgroup >= 0 { | ||||
| 			native.PutUint32(b, uint32(rule.SuppressIfgroup)) | ||||
| 			req.AddData(nl.NewRtAttr(nl.FRA_SUPPRESS_IFGROUP, b)) | ||||
| 		} | ||||
| 	} | ||||
| 	if rule.IifName != "" { | ||||
| 		req.AddData(nl.NewRtAttr(nl.FRA_IIFNAME, []byte(rule.IifName))) | ||||
| 	} | ||||
| 	if rule.OifName != "" { | ||||
| 		req.AddData(nl.NewRtAttr(nl.FRA_OIFNAME, []byte(rule.OifName))) | ||||
| 	} | ||||
| 	if rule.Goto >= 0 { | ||||
| 		msg.Type = nl.FR_ACT_NOP | ||||
| 		native.PutUint32(b, uint32(rule.Goto)) | ||||
| 		req.AddData(nl.NewRtAttr(nl.FRA_GOTO, b)) | ||||
| 	} | ||||
|  | ||||
| 	_, err := req.Execute(syscall.NETLINK_ROUTE, 0) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // RuleList lists rules in the system. | ||||
| // Equivalent to: ip rule list | ||||
| func RuleList(family int) ([]Rule, error) { | ||||
| 	req := nl.NewNetlinkRequest(syscall.RTM_GETRULE, syscall.NLM_F_DUMP|syscall.NLM_F_REQUEST) | ||||
| 	msg := nl.NewIfInfomsg(family) | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWRULE) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	native := nl.NativeEndian() | ||||
| 	var res = make([]Rule, 0) | ||||
| 	for i := range msgs { | ||||
| 		msg := nl.DeserializeRtMsg(msgs[i]) | ||||
| 		attrs, err := nl.ParseRouteAttr(msgs[i][msg.Len():]) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		rule := NewRule() | ||||
| 		rule.RtMsg = msg | ||||
|  | ||||
| 		for j := range attrs { | ||||
| 			switch attrs[j].Attr.Type { | ||||
| 			case syscall.RTA_TABLE: | ||||
| 				rule.Table = int(native.Uint32(attrs[j].Value[0:4])) | ||||
| 			case nl.FRA_SRC: | ||||
| 				rule.Src = &net.IPNet{ | ||||
| 					IP:   attrs[j].Value, | ||||
| 					Mask: net.CIDRMask(int(msg.Src_len), 8*len(attrs[j].Value)), | ||||
| 				} | ||||
| 			case nl.FRA_DST: | ||||
| 				rule.Dst = &net.IPNet{ | ||||
| 					IP:   attrs[j].Value, | ||||
| 					Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attrs[j].Value)), | ||||
| 				} | ||||
| 			case nl.FRA_FWMARK: | ||||
| 				rule.Mark = int(native.Uint32(attrs[j].Value[0:4])) | ||||
| 			case nl.FRA_FWMASK: | ||||
| 				rule.Mask = int(native.Uint32(attrs[j].Value[0:4])) | ||||
| 			case nl.FRA_TUN_ID: | ||||
| 				rule.TunID = uint(native.Uint64(attrs[j].Value[0:4])) | ||||
| 			case nl.FRA_IIFNAME: | ||||
| 				rule.IifName = string(attrs[j].Value[:len(attrs[j].Value)-1]) | ||||
| 			case nl.FRA_OIFNAME: | ||||
| 				rule.OifName = string(attrs[j].Value[:len(attrs[j].Value)-1]) | ||||
| 			case nl.FRA_SUPPRESS_PREFIXLEN: | ||||
| 				i := native.Uint32(attrs[j].Value[0:4]) | ||||
| 				if i != 0xffffffff { | ||||
| 					rule.SuppressPrefixlen = int(i) | ||||
| 				} | ||||
| 			case nl.FRA_SUPPRESS_IFGROUP: | ||||
| 				i := native.Uint32(attrs[j].Value[0:4]) | ||||
| 				if i != 0xffffffff { | ||||
| 					rule.SuppressIfgroup = int(i) | ||||
| 				} | ||||
| 			case nl.FRA_FLOW: | ||||
| 				rule.Flow = int(native.Uint32(attrs[j].Value[0:4])) | ||||
| 			case nl.FRA_GOTO: | ||||
| 				rule.Goto = int(native.Uint32(attrs[j].Value[0:4])) | ||||
| 			case nl.FRA_PRIORITY: | ||||
| 				rule.Priority = int(native.Uint32(attrs[j].Value[0:4])) | ||||
| 			} | ||||
| 		} | ||||
| 		res = append(res, *rule) | ||||
| 	} | ||||
|  | ||||
| 	return res, nil | ||||
| } | ||||
							
								
								
									
										64
									
								
								vendor/github.com/vishvananda/netlink/xfrm.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/vishvananda/netlink/xfrm.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,64 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"syscall" | ||||
| ) | ||||
|  | ||||
| // Proto is an enum representing an ipsec protocol. | ||||
| type Proto uint8 | ||||
|  | ||||
| const ( | ||||
| 	XFRM_PROTO_ROUTE2    Proto = syscall.IPPROTO_ROUTING | ||||
| 	XFRM_PROTO_ESP       Proto = syscall.IPPROTO_ESP | ||||
| 	XFRM_PROTO_AH        Proto = syscall.IPPROTO_AH | ||||
| 	XFRM_PROTO_HAO       Proto = syscall.IPPROTO_DSTOPTS | ||||
| 	XFRM_PROTO_COMP      Proto = syscall.IPPROTO_COMP | ||||
| 	XFRM_PROTO_IPSEC_ANY Proto = syscall.IPPROTO_RAW | ||||
| ) | ||||
|  | ||||
| func (p Proto) String() string { | ||||
| 	switch p { | ||||
| 	case XFRM_PROTO_ROUTE2: | ||||
| 		return "route2" | ||||
| 	case XFRM_PROTO_ESP: | ||||
| 		return "esp" | ||||
| 	case XFRM_PROTO_AH: | ||||
| 		return "ah" | ||||
| 	case XFRM_PROTO_HAO: | ||||
| 		return "hao" | ||||
| 	case XFRM_PROTO_COMP: | ||||
| 		return "comp" | ||||
| 	case XFRM_PROTO_IPSEC_ANY: | ||||
| 		return "ipsec-any" | ||||
| 	} | ||||
| 	return fmt.Sprintf("%d", p) | ||||
| } | ||||
|  | ||||
| // Mode is an enum representing an ipsec transport. | ||||
| type Mode uint8 | ||||
|  | ||||
| const ( | ||||
| 	XFRM_MODE_TRANSPORT Mode = iota | ||||
| 	XFRM_MODE_TUNNEL | ||||
| 	XFRM_MODE_ROUTEOPTIMIZATION | ||||
| 	XFRM_MODE_IN_TRIGGER | ||||
| 	XFRM_MODE_BEET | ||||
| 	XFRM_MODE_MAX | ||||
| ) | ||||
|  | ||||
| func (m Mode) String() string { | ||||
| 	switch m { | ||||
| 	case XFRM_MODE_TRANSPORT: | ||||
| 		return "transport" | ||||
| 	case XFRM_MODE_TUNNEL: | ||||
| 		return "tunnel" | ||||
| 	case XFRM_MODE_ROUTEOPTIMIZATION: | ||||
| 		return "ro" | ||||
| 	case XFRM_MODE_IN_TRIGGER: | ||||
| 		return "in_trigger" | ||||
| 	case XFRM_MODE_BEET: | ||||
| 		return "beet" | ||||
| 	} | ||||
| 	return fmt.Sprintf("%d", m) | ||||
| } | ||||
							
								
								
									
										59
									
								
								vendor/github.com/vishvananda/netlink/xfrm_policy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										59
									
								
								vendor/github.com/vishvananda/netlink/xfrm_policy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,59 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| ) | ||||
|  | ||||
| // Dir is an enum representing an ipsec template direction. | ||||
| type Dir uint8 | ||||
|  | ||||
| const ( | ||||
| 	XFRM_DIR_IN Dir = iota | ||||
| 	XFRM_DIR_OUT | ||||
| 	XFRM_DIR_FWD | ||||
| 	XFRM_SOCKET_IN | ||||
| 	XFRM_SOCKET_OUT | ||||
| 	XFRM_SOCKET_FWD | ||||
| ) | ||||
|  | ||||
| func (d Dir) String() string { | ||||
| 	switch d { | ||||
| 	case XFRM_DIR_IN: | ||||
| 		return "dir in" | ||||
| 	case XFRM_DIR_OUT: | ||||
| 		return "dir out" | ||||
| 	case XFRM_DIR_FWD: | ||||
| 		return "dir fwd" | ||||
| 	case XFRM_SOCKET_IN: | ||||
| 		return "socket in" | ||||
| 	case XFRM_SOCKET_OUT: | ||||
| 		return "socket out" | ||||
| 	case XFRM_SOCKET_FWD: | ||||
| 		return "socket fwd" | ||||
| 	} | ||||
| 	return fmt.Sprintf("socket %d", d-XFRM_SOCKET_IN) | ||||
| } | ||||
|  | ||||
| // XfrmPolicyTmpl encapsulates a rule for the base addresses of an ipsec | ||||
| // policy. These rules are matched with XfrmState to determine encryption | ||||
| // and authentication algorithms. | ||||
| type XfrmPolicyTmpl struct { | ||||
| 	Dst   net.IP | ||||
| 	Src   net.IP | ||||
| 	Proto Proto | ||||
| 	Mode  Mode | ||||
| 	Reqid int | ||||
| } | ||||
|  | ||||
| // XfrmPolicy represents an ipsec policy. It represents the overlay network | ||||
| // and has a list of XfrmPolicyTmpls representing the base addresses of | ||||
| // the policy. | ||||
| type XfrmPolicy struct { | ||||
| 	Dst      *net.IPNet | ||||
| 	Src      *net.IPNet | ||||
| 	Dir      Dir | ||||
| 	Priority int | ||||
| 	Index    int | ||||
| 	Tmpls    []XfrmPolicyTmpl | ||||
| } | ||||
							
								
								
									
										127
									
								
								vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										127
									
								
								vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,127 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"syscall" | ||||
|  | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
|  | ||||
| func selFromPolicy(sel *nl.XfrmSelector, policy *XfrmPolicy) { | ||||
| 	sel.Family = uint16(nl.GetIPFamily(policy.Dst.IP)) | ||||
| 	sel.Daddr.FromIP(policy.Dst.IP) | ||||
| 	sel.Saddr.FromIP(policy.Src.IP) | ||||
| 	prefixlenD, _ := policy.Dst.Mask.Size() | ||||
| 	sel.PrefixlenD = uint8(prefixlenD) | ||||
| 	prefixlenS, _ := policy.Src.Mask.Size() | ||||
| 	sel.PrefixlenS = uint8(prefixlenS) | ||||
| } | ||||
|  | ||||
| // XfrmPolicyAdd will add an xfrm policy to the system. | ||||
| // Equivalent to: `ip xfrm policy add $policy` | ||||
| func XfrmPolicyAdd(policy *XfrmPolicy) error { | ||||
| 	req := nl.NewNetlinkRequest(nl.XFRM_MSG_NEWPOLICY, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) | ||||
|  | ||||
| 	msg := &nl.XfrmUserpolicyInfo{} | ||||
| 	selFromPolicy(&msg.Sel, policy) | ||||
| 	msg.Priority = uint32(policy.Priority) | ||||
| 	msg.Index = uint32(policy.Index) | ||||
| 	msg.Dir = uint8(policy.Dir) | ||||
| 	msg.Lft.SoftByteLimit = nl.XFRM_INF | ||||
| 	msg.Lft.HardByteLimit = nl.XFRM_INF | ||||
| 	msg.Lft.SoftPacketLimit = nl.XFRM_INF | ||||
| 	msg.Lft.HardPacketLimit = nl.XFRM_INF | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	tmplData := make([]byte, nl.SizeofXfrmUserTmpl*len(policy.Tmpls)) | ||||
| 	for i, tmpl := range policy.Tmpls { | ||||
| 		start := i * nl.SizeofXfrmUserTmpl | ||||
| 		userTmpl := nl.DeserializeXfrmUserTmpl(tmplData[start : start+nl.SizeofXfrmUserTmpl]) | ||||
| 		userTmpl.XfrmId.Daddr.FromIP(tmpl.Dst) | ||||
| 		userTmpl.Saddr.FromIP(tmpl.Src) | ||||
| 		userTmpl.XfrmId.Proto = uint8(tmpl.Proto) | ||||
| 		userTmpl.Mode = uint8(tmpl.Mode) | ||||
| 		userTmpl.Reqid = uint32(tmpl.Reqid) | ||||
| 		userTmpl.Aalgos = ^uint32(0) | ||||
| 		userTmpl.Ealgos = ^uint32(0) | ||||
| 		userTmpl.Calgos = ^uint32(0) | ||||
| 	} | ||||
| 	if len(tmplData) > 0 { | ||||
| 		tmpls := nl.NewRtAttr(nl.XFRMA_TMPL, tmplData) | ||||
| 		req.AddData(tmpls) | ||||
| 	} | ||||
|  | ||||
| 	_, err := req.Execute(syscall.NETLINK_XFRM, 0) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // XfrmPolicyDel will delete an xfrm policy from the system. Note that | ||||
| // the Tmpls are ignored when matching the policy to delete. | ||||
| // Equivalent to: `ip xfrm policy del $policy` | ||||
| func XfrmPolicyDel(policy *XfrmPolicy) error { | ||||
| 	req := nl.NewNetlinkRequest(nl.XFRM_MSG_DELPOLICY, syscall.NLM_F_ACK) | ||||
|  | ||||
| 	msg := &nl.XfrmUserpolicyId{} | ||||
| 	selFromPolicy(&msg.Sel, policy) | ||||
| 	msg.Index = uint32(policy.Index) | ||||
| 	msg.Dir = uint8(policy.Dir) | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	_, err := req.Execute(syscall.NETLINK_XFRM, 0) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // XfrmPolicyList gets a list of xfrm policies in the system. | ||||
| // Equivalent to: `ip xfrm policy show`. | ||||
| // The list can be filtered by ip family. | ||||
| func XfrmPolicyList(family int) ([]XfrmPolicy, error) { | ||||
| 	req := nl.NewNetlinkRequest(nl.XFRM_MSG_GETPOLICY, syscall.NLM_F_DUMP) | ||||
|  | ||||
| 	msg := nl.NewIfInfomsg(family) | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	msgs, err := req.Execute(syscall.NETLINK_XFRM, nl.XFRM_MSG_NEWPOLICY) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var res []XfrmPolicy | ||||
| 	for _, m := range msgs { | ||||
| 		msg := nl.DeserializeXfrmUserpolicyInfo(m) | ||||
|  | ||||
| 		if family != FAMILY_ALL && family != int(msg.Sel.Family) { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		var policy XfrmPolicy | ||||
|  | ||||
| 		policy.Dst = msg.Sel.Daddr.ToIPNet(msg.Sel.PrefixlenD) | ||||
| 		policy.Src = msg.Sel.Saddr.ToIPNet(msg.Sel.PrefixlenS) | ||||
| 		policy.Priority = int(msg.Priority) | ||||
| 		policy.Index = int(msg.Index) | ||||
| 		policy.Dir = Dir(msg.Dir) | ||||
|  | ||||
| 		attrs, err := nl.ParseRouteAttr(m[msg.Len():]) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		for _, attr := range attrs { | ||||
| 			switch attr.Attr.Type { | ||||
| 			case nl.XFRMA_TMPL: | ||||
| 				max := len(attr.Value) | ||||
| 				for i := 0; i < max; i += nl.SizeofXfrmUserTmpl { | ||||
| 					var resTmpl XfrmPolicyTmpl | ||||
| 					tmpl := nl.DeserializeXfrmUserTmpl(attr.Value[i : i+nl.SizeofXfrmUserTmpl]) | ||||
| 					resTmpl.Dst = tmpl.XfrmId.Daddr.ToIP() | ||||
| 					resTmpl.Src = tmpl.Saddr.ToIP() | ||||
| 					resTmpl.Proto = Proto(tmpl.XfrmId.Proto) | ||||
| 					resTmpl.Mode = Mode(tmpl.Mode) | ||||
| 					resTmpl.Reqid = int(tmpl.Reqid) | ||||
| 					policy.Tmpls = append(policy.Tmpls, resTmpl) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		res = append(res, policy) | ||||
| 	} | ||||
| 	return res, nil | ||||
| } | ||||
							
								
								
									
										53
									
								
								vendor/github.com/vishvananda/netlink/xfrm_state.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										53
									
								
								vendor/github.com/vishvananda/netlink/xfrm_state.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,53 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"net" | ||||
| ) | ||||
|  | ||||
| // XfrmStateAlgo represents the algorithm to use for the ipsec encryption. | ||||
| type XfrmStateAlgo struct { | ||||
| 	Name        string | ||||
| 	Key         []byte | ||||
| 	TruncateLen int // Auth only | ||||
| } | ||||
|  | ||||
| // EncapType is an enum representing an ipsec template direction. | ||||
| type EncapType uint8 | ||||
|  | ||||
| const ( | ||||
| 	XFRM_ENCAP_ESPINUDP_NONIKE EncapType = iota + 1 | ||||
| 	XFRM_ENCAP_ESPINUDP | ||||
| ) | ||||
|  | ||||
| func (e EncapType) String() string { | ||||
| 	switch e { | ||||
| 	case XFRM_ENCAP_ESPINUDP_NONIKE: | ||||
| 		return "espinudp-nonike" | ||||
| 	case XFRM_ENCAP_ESPINUDP: | ||||
| 		return "espinudp" | ||||
| 	} | ||||
| 	return "unknown" | ||||
| } | ||||
|  | ||||
| // XfrmEncap represents the encapsulation to use for the ipsec encryption. | ||||
| type XfrmStateEncap struct { | ||||
| 	Type            EncapType | ||||
| 	SrcPort         int | ||||
| 	DstPort         int | ||||
| 	OriginalAddress net.IP | ||||
| } | ||||
|  | ||||
| // XfrmState represents the state of an ipsec policy. It optionally | ||||
| // contains an XfrmStateAlgo for encryption and one for authentication. | ||||
| type XfrmState struct { | ||||
| 	Dst          net.IP | ||||
| 	Src          net.IP | ||||
| 	Proto        Proto | ||||
| 	Mode         Mode | ||||
| 	Spi          int | ||||
| 	Reqid        int | ||||
| 	ReplayWindow int | ||||
| 	Auth         *XfrmStateAlgo | ||||
| 	Crypt        *XfrmStateAlgo | ||||
| 	Encap        *XfrmStateEncap | ||||
| } | ||||
							
								
								
									
										181
									
								
								vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										181
									
								
								vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,181 +0,0 @@ | ||||
| package netlink | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"syscall" | ||||
|  | ||||
| 	"github.com/vishvananda/netlink/nl" | ||||
| ) | ||||
|  | ||||
| func writeStateAlgo(a *XfrmStateAlgo) []byte { | ||||
| 	algo := nl.XfrmAlgo{ | ||||
| 		AlgKeyLen: uint32(len(a.Key) * 8), | ||||
| 		AlgKey:    a.Key, | ||||
| 	} | ||||
| 	end := len(a.Name) | ||||
| 	if end > 64 { | ||||
| 		end = 64 | ||||
| 	} | ||||
| 	copy(algo.AlgName[:end], a.Name) | ||||
| 	return algo.Serialize() | ||||
| } | ||||
|  | ||||
| func writeStateAlgoAuth(a *XfrmStateAlgo) []byte { | ||||
| 	algo := nl.XfrmAlgoAuth{ | ||||
| 		AlgKeyLen:   uint32(len(a.Key) * 8), | ||||
| 		AlgTruncLen: uint32(a.TruncateLen), | ||||
| 		AlgKey:      a.Key, | ||||
| 	} | ||||
| 	end := len(a.Name) | ||||
| 	if end > 64 { | ||||
| 		end = 64 | ||||
| 	} | ||||
| 	copy(algo.AlgName[:end], a.Name) | ||||
| 	return algo.Serialize() | ||||
| } | ||||
|  | ||||
| // XfrmStateAdd will add an xfrm state to the system. | ||||
| // Equivalent to: `ip xfrm state add $state` | ||||
| func XfrmStateAdd(state *XfrmState) error { | ||||
| 	// A state with spi 0 can't be deleted so don't allow it to be set | ||||
| 	if state.Spi == 0 { | ||||
| 		return fmt.Errorf("Spi must be set when adding xfrm state.") | ||||
| 	} | ||||
| 	req := nl.NewNetlinkRequest(nl.XFRM_MSG_NEWSA, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) | ||||
|  | ||||
| 	msg := &nl.XfrmUsersaInfo{} | ||||
| 	msg.Family = uint16(nl.GetIPFamily(state.Dst)) | ||||
| 	msg.Id.Daddr.FromIP(state.Dst) | ||||
| 	msg.Saddr.FromIP(state.Src) | ||||
| 	msg.Id.Proto = uint8(state.Proto) | ||||
| 	msg.Mode = uint8(state.Mode) | ||||
| 	msg.Id.Spi = nl.Swap32(uint32(state.Spi)) | ||||
| 	msg.Reqid = uint32(state.Reqid) | ||||
| 	msg.ReplayWindow = uint8(state.ReplayWindow) | ||||
| 	msg.Lft.SoftByteLimit = nl.XFRM_INF | ||||
| 	msg.Lft.HardByteLimit = nl.XFRM_INF | ||||
| 	msg.Lft.SoftPacketLimit = nl.XFRM_INF | ||||
| 	msg.Lft.HardPacketLimit = nl.XFRM_INF | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	if state.Auth != nil { | ||||
| 		out := nl.NewRtAttr(nl.XFRMA_ALG_AUTH_TRUNC, writeStateAlgoAuth(state.Auth)) | ||||
| 		req.AddData(out) | ||||
| 	} | ||||
| 	if state.Crypt != nil { | ||||
| 		out := nl.NewRtAttr(nl.XFRMA_ALG_CRYPT, writeStateAlgo(state.Crypt)) | ||||
| 		req.AddData(out) | ||||
| 	} | ||||
| 	if state.Encap != nil { | ||||
| 		encapData := make([]byte, nl.SizeofXfrmEncapTmpl) | ||||
| 		encap := nl.DeserializeXfrmEncapTmpl(encapData) | ||||
| 		encap.EncapType = uint16(state.Encap.Type) | ||||
| 		encap.EncapSport = nl.Swap16(uint16(state.Encap.SrcPort)) | ||||
| 		encap.EncapDport = nl.Swap16(uint16(state.Encap.DstPort)) | ||||
| 		encap.EncapOa.FromIP(state.Encap.OriginalAddress) | ||||
| 		out := nl.NewRtAttr(nl.XFRMA_ENCAP, encapData) | ||||
| 		req.AddData(out) | ||||
| 	} | ||||
|  | ||||
| 	_, err := req.Execute(syscall.NETLINK_XFRM, 0) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // XfrmStateDel will delete an xfrm state from the system. Note that | ||||
| // the Algos are ignored when matching the state to delete. | ||||
| // Equivalent to: `ip xfrm state del $state` | ||||
| func XfrmStateDel(state *XfrmState) error { | ||||
| 	req := nl.NewNetlinkRequest(nl.XFRM_MSG_DELSA, syscall.NLM_F_ACK) | ||||
|  | ||||
| 	msg := &nl.XfrmUsersaId{} | ||||
| 	msg.Daddr.FromIP(state.Dst) | ||||
| 	msg.Family = uint16(nl.GetIPFamily(state.Dst)) | ||||
| 	msg.Proto = uint8(state.Proto) | ||||
| 	msg.Spi = nl.Swap32(uint32(state.Spi)) | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	saddr := nl.XfrmAddress{} | ||||
| 	saddr.FromIP(state.Src) | ||||
| 	srcdata := nl.NewRtAttr(nl.XFRMA_SRCADDR, saddr.Serialize()) | ||||
|  | ||||
| 	req.AddData(srcdata) | ||||
|  | ||||
| 	_, err := req.Execute(syscall.NETLINK_XFRM, 0) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // XfrmStateList gets a list of xfrm states in the system. | ||||
| // Equivalent to: `ip xfrm state show`. | ||||
| // The list can be filtered by ip family. | ||||
| func XfrmStateList(family int) ([]XfrmState, error) { | ||||
| 	req := nl.NewNetlinkRequest(nl.XFRM_MSG_GETSA, syscall.NLM_F_DUMP) | ||||
|  | ||||
| 	msg := nl.NewIfInfomsg(family) | ||||
| 	req.AddData(msg) | ||||
|  | ||||
| 	msgs, err := req.Execute(syscall.NETLINK_XFRM, nl.XFRM_MSG_NEWSA) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var res []XfrmState | ||||
| 	for _, m := range msgs { | ||||
| 		msg := nl.DeserializeXfrmUsersaInfo(m) | ||||
|  | ||||
| 		if family != FAMILY_ALL && family != int(msg.Family) { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		var state XfrmState | ||||
|  | ||||
| 		state.Dst = msg.Id.Daddr.ToIP() | ||||
| 		state.Src = msg.Saddr.ToIP() | ||||
| 		state.Proto = Proto(msg.Id.Proto) | ||||
| 		state.Mode = Mode(msg.Mode) | ||||
| 		state.Spi = int(nl.Swap32(msg.Id.Spi)) | ||||
| 		state.Reqid = int(msg.Reqid) | ||||
| 		state.ReplayWindow = int(msg.ReplayWindow) | ||||
|  | ||||
| 		attrs, err := nl.ParseRouteAttr(m[msg.Len():]) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		for _, attr := range attrs { | ||||
| 			switch attr.Attr.Type { | ||||
| 			case nl.XFRMA_ALG_AUTH, nl.XFRMA_ALG_CRYPT: | ||||
| 				var resAlgo *XfrmStateAlgo | ||||
| 				if attr.Attr.Type == nl.XFRMA_ALG_AUTH { | ||||
| 					if state.Auth == nil { | ||||
| 						state.Auth = new(XfrmStateAlgo) | ||||
| 					} | ||||
| 					resAlgo = state.Auth | ||||
| 				} else { | ||||
| 					state.Crypt = new(XfrmStateAlgo) | ||||
| 					resAlgo = state.Crypt | ||||
| 				} | ||||
| 				algo := nl.DeserializeXfrmAlgo(attr.Value[:]) | ||||
| 				(*resAlgo).Name = nl.BytesToString(algo.AlgName[:]) | ||||
| 				(*resAlgo).Key = algo.AlgKey | ||||
| 			case nl.XFRMA_ALG_AUTH_TRUNC: | ||||
| 				if state.Auth == nil { | ||||
| 					state.Auth = new(XfrmStateAlgo) | ||||
| 				} | ||||
| 				algo := nl.DeserializeXfrmAlgoAuth(attr.Value[:]) | ||||
| 				state.Auth.Name = nl.BytesToString(algo.AlgName[:]) | ||||
| 				state.Auth.Key = algo.AlgKey | ||||
| 				state.Auth.TruncateLen = int(algo.AlgTruncLen) | ||||
| 			case nl.XFRMA_ENCAP: | ||||
| 				encap := nl.DeserializeXfrmEncapTmpl(attr.Value[:]) | ||||
| 				state.Encap = new(XfrmStateEncap) | ||||
| 				state.Encap.Type = EncapType(encap.EncapType) | ||||
| 				state.Encap.SrcPort = int(nl.Swap16(encap.EncapSport)) | ||||
| 				state.Encap.DstPort = int(nl.Swap16(encap.EncapDport)) | ||||
| 				state.Encap.OriginalAddress = encap.EncapOa.ToIP() | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
| 		res = append(res, state) | ||||
| 	} | ||||
| 	return res, nil | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Michael Crosby
					Michael Crosby