forked from ligato/vpp-agent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gre_vppcalls.go
90 lines (77 loc) · 2.37 KB
/
gre_vppcalls.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package vpp1904
import (
"errors"
"net"
interfaces "github.com/ligato/vpp-agent/api/models/vpp/interfaces"
"github.com/ligato/vpp-agent/plugins/vpp/binapi/vpp1904/gre"
)
func (h *InterfaceVppHandler) greAddDelTunnel(isAdd uint8, greLink *interfaces.GreLink) (uint32, error) {
if greLink.TunnelType == interfaces.GreLink_UNKNOWN {
err := errors.New("bad GRE tunnel type")
return 0, err
}
greSource := net.ParseIP(greLink.SrcAddr)
if greSource == nil {
err := errors.New("bad source address for GRE tunnel")
return 0, err
}
greDestination := net.ParseIP(greLink.DstAddr)
if greDestination == nil {
err := errors.New("bad destination address for GRE tunnel")
return 0, err
}
if greLink.SrcAddr == greLink.DstAddr {
err := errors.New("source and destination are the same")
return 0, err
}
if greLink.TunnelType == interfaces.GreLink_ERSPAN && greLink.SessionId > 1023 {
err := errors.New("set session id for ERSPAN tunnel type")
return 0, err
}
req := &gre.GreAddDelTunnel{
IsAdd: isAdd,
TunnelType: uint8(greLink.TunnelType - 1),
Instance: ^uint32(0),
OuterFibID: greLink.OuterFibId,
SessionID: uint16(greLink.SessionId),
}
var isSrcIPv6, isDstIPv6 bool
if greSource.To4() == nil {
isSrcIPv6 = true
}
if greDestination.To4() == nil {
isDstIPv6 = true
}
if isSrcIPv6 != isDstIPv6 {
return 0, errors.New("source and destination addresses must be both either in IPv4 or IPv6")
}
if isSrcIPv6 {
req.SrcAddress = []byte(greSource.To16())
req.DstAddress = []byte(greDestination.To16())
req.IsIPv6 = 1
} else {
req.SrcAddress = []byte(greSource.To4())
req.DstAddress = []byte(greDestination.To4())
}
reply := &gre.GreAddDelTunnelReply{}
if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil {
return 0, err
}
return reply.SwIfIndex, nil
}
// AddGreTunnel adds new GRE interface.
func (h *InterfaceVppHandler) AddGreTunnel(ifName string, greLink *interfaces.GreLink) (uint32, error) {
swIfIndex, err := h.greAddDelTunnel(1, greLink)
if err != nil {
return 0, err
}
return swIfIndex, h.SetInterfaceTag(ifName, swIfIndex)
}
// DelGreTunnel removes GRE interface.
func (h *InterfaceVppHandler) DelGreTunnel(ifName string, greLink *interfaces.GreLink) (uint32, error) {
swIfIndex, err := h.greAddDelTunnel(0, greLink)
if err != nil {
return 0, err
}
return swIfIndex, h.RemoveInterfaceTag(ifName, swIfIndex)
}