-
Notifications
You must be signed in to change notification settings - Fork 1
/
nethop.go
92 lines (75 loc) · 1.96 KB
/
nethop.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
91
92
package rib
import (
"fmt"
"net/netip"
"mmesh.dev/m-api-go/grpc/network/nac"
"mmesh.dev/m-api-go/grpc/network/routing"
"mmesh.dev/m-lib/pkg/xlog"
)
func (r *ribData) CheckIPDst(addr *netip.Addr) error {
r.RLock()
defer r.RUnlock()
// get route ipDst
ipDst := getIPDstFromRIB(addr, r.rib)
if len(ipDst) == 0 {
return fmt.Errorf("no routing entry for %s", addr)
}
return nil
}
func (r *ribData) GetNetHop(addr *netip.Addr) (*routing.NetHop, error) {
r.RLock()
defer r.RUnlock()
// get route ipDst
ipDst := getIPDstFromRIB(addr, r.rib)
if len(ipDst) == 0 {
return nil, fmt.Errorf("no routing entry for %s", addr)
}
re, ok := r.rib.RoutingTable[ipDst]
if !ok {
return nil, fmt.Errorf("no routing entry for %s", addr)
}
var netHop *routing.NetHop
var prio int32
for _, nh := range re.Gw {
if nh.Priority < prio || prio == 0 {
prio = nh.Priority
netHop = nh
}
}
if netHop == nil {
return nil, fmt.Errorf("no routing entry for %s", addr)
}
return netHop, nil
}
func getIPDstFromRIB(addr *netip.Addr, r *routing.RIB) string {
// try first internal routes
ipv4Dst := addr.String() + "/32"
if re, ok := r.RoutingTable[ipv4Dst]; ok {
if re.SubnetID == r.RoutingDomain.SubnetID || r.RoutingDomain.Scope == nac.RoutingScope_NETWORK {
return ipv4Dst
}
}
ipv6Dst := addr.String() + "/128"
if re, ok := r.RoutingTable[ipv6Dst]; ok {
if len(re.SubnetID) == 0 && re.Type == routing.RouteType_PROXY {
return ipv6Dst
}
if re.SubnetID == r.RoutingDomain.SubnetID || r.RoutingDomain.Scope == nac.RoutingScope_NETWORK {
return ipv6Dst
}
}
// then static routes
for ipDst, re := range r.RoutingTable {
netCIDR, err := netip.ParsePrefix(ipDst)
if err != nil {
xlog.Alertf("Detected invalid route %s (please check your configs): %v", ipDst, err)
continue
}
if netCIDR.Contains(*addr) {
if re.SubnetID == r.RoutingDomain.SubnetID || r.RoutingDomain.Scope == nac.RoutingScope_NETWORK {
return ipDst
}
}
}
return ""
}