26
26
)
27
27
28
28
type ifaceCache struct {
29
- ifMap map [string ]* Interface
30
- ifTable bart.Table [* Interface ]
29
+ ifMapByName map [string ]* Interface
30
+ ifMapByAddr map [netip.Addr ]* Interface
31
+ ifTable bart.Table [* Interface ]
31
32
}
32
33
33
34
var caches = singledo.NewSingle [* ifaceCache ](time .Second * 20 )
@@ -40,7 +41,8 @@ func getCache() (*ifaceCache, error) {
40
41
}
41
42
42
43
cache := & ifaceCache {
43
- ifMap : make (map [string ]* Interface ),
44
+ ifMapByName : make (map [string ]* Interface ),
45
+ ifMapByAddr : make (map [netip.Addr ]* Interface ),
44
46
}
45
47
46
48
for _ , iface := range ifaces {
@@ -78,12 +80,13 @@ func getCache() (*ifaceCache, error) {
78
80
Flags : iface .Flags ,
79
81
Addresses : ipNets ,
80
82
}
81
- cache .ifMap [iface .Name ] = ifaceObj
83
+ cache .ifMapByName [iface .Name ] = ifaceObj
82
84
83
85
if iface .Flags & net .FlagUp == 0 {
84
86
continue // interface down
85
87
}
86
88
for _ , prefix := range ipNets {
89
+ cache .ifMapByAddr [prefix .Addr ()] = ifaceObj
87
90
cache .ifTable .Insert (prefix , ifaceObj )
88
91
}
89
92
}
@@ -98,7 +101,7 @@ func Interfaces() (map[string]*Interface, error) {
98
101
if err != nil {
99
102
return nil , err
100
103
}
101
- return cache .ifMap , nil
104
+ return cache .ifMapByName , nil
102
105
}
103
106
104
107
func ResolveInterface (name string ) (* Interface , error ) {
@@ -120,6 +123,11 @@ func ResolveInterfaceByAddr(addr netip.Addr) (*Interface, error) {
120
123
if err != nil {
121
124
return nil , err
122
125
}
126
+ // maybe two interfaces have the same prefix but different address
127
+ // so direct check address equal before do a route lookup (longest prefix match)
128
+ if iface , ok := cache .ifMapByAddr [addr ]; ok {
129
+ return iface , nil
130
+ }
123
131
iface , ok := cache .ifTable .Lookup (addr )
124
132
if ! ok {
125
133
return nil , ErrIfaceNotFound
@@ -133,7 +141,8 @@ func IsLocalIp(addr netip.Addr) (bool, error) {
133
141
if err != nil {
134
142
return false , err
135
143
}
136
- return cache .ifTable .Contains (addr ), nil
144
+ _ , ok := cache .ifMapByAddr [addr ]
145
+ return ok , nil
137
146
}
138
147
139
148
func FlushCache () {
0 commit comments