ipip.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. // Copyright 2019 the Kilo authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package iproute
  15. import (
  16. "bytes"
  17. "fmt"
  18. "os/exec"
  19. "github.com/vishvananda/netlink"
  20. )
  21. const (
  22. ipipHeaderSize = 20
  23. tunnelName = "tunl0"
  24. )
  25. // NewIPIP creates an IPIP interface using the base interface
  26. // to derive the tunnel's MTU.
  27. func NewIPIP(baseIndex int) (int, error) {
  28. link, err := netlink.LinkByName(tunnelName)
  29. if err != nil {
  30. // If we failed to find the tunnel, then it probably simply does not exist.
  31. cmd := exec.Command("ip", "tunnel", "add", tunnelName, "mode", "ipip")
  32. var stderr bytes.Buffer
  33. cmd.Stderr = &stderr
  34. if err := cmd.Run(); err != nil {
  35. return 0, fmt.Errorf("failed to create IPIP tunnel: %s", stderr.String())
  36. }
  37. link, err = netlink.LinkByName(tunnelName)
  38. if err != nil {
  39. return 0, fmt.Errorf("failed to get tunnel device: %v", err)
  40. }
  41. }
  42. base, err := netlink.LinkByIndex(baseIndex)
  43. if err != nil {
  44. return 0, fmt.Errorf("failed to get base device: %v", err)
  45. }
  46. mtu := base.Attrs().MTU - ipipHeaderSize
  47. if err = netlink.LinkSetMTU(link, mtu); err != nil {
  48. return 0, fmt.Errorf("failed to set tunnel MTU: %v", err)
  49. }
  50. return link.Attrs().Index, nil
  51. }