1
1
package pass1
2
2
3
3
import (
4
- "maps"
5
4
"net/netip"
6
- "slices"
7
5
"strings"
8
6
9
7
"go4.org/netipx"
@@ -53,28 +51,31 @@ func (c *spoc) checkSubnetOf() {
53
51
}
54
52
55
53
func (c * spoc ) checkIPAddressesAndBridges () {
56
- prefix2net := make (map [string ][]* network )
54
+ type nameV46 struct {
55
+ name string
56
+ v6 bool
57
+ }
58
+ prefix2net := make (map [nameV46 ][]* network )
57
59
for _ , n := range c .allNetworks {
58
- // Group bridged networks by prefix of name.
60
+ // Group bridged networks by IPv4/v6 type and prefix of name.
59
61
if n .ipType == bridgedIP {
60
62
prefix , _ , _ := strings .Cut (n .name , "/" )
61
- prefix2net [prefix ] = append (prefix2net [prefix ], n )
63
+ prefixV46 := nameV46 {prefix , n .ipV6 }
64
+ prefix2net [prefixV46 ] = append (prefix2net [prefixV46 ], n )
62
65
} else if n .ipType == unnumberedIP {
63
66
l := n .interfaces
64
67
if len (l ) > 2 {
65
68
c .err (
66
69
"Unnumbered %s is connected to more than two interfaces:\n %s" ,
67
- n .name , l .nameList ())
70
+ n .vxName () , l .nameList ())
68
71
}
69
72
} else if ! (n .ipType == tunnelIP || n .loopback ) {
70
73
c .checkIPAddr (n )
71
74
}
72
75
}
73
76
74
77
// Check address conflicts for collected parts of bridged networks.
75
- // Sort prefix names for deterministic error messages.
76
- for _ , prefix := range slices .Sorted (maps .Keys (prefix2net )) {
77
- l := prefix2net [prefix ]
78
+ for prefixV46 , l := range prefix2net {
78
79
dummy := new (network )
79
80
seen := make (map [* routerIntf ]bool )
80
81
for _ , n := range l {
@@ -91,7 +92,7 @@ func (c *spoc) checkIPAddressesAndBridges() {
91
92
c .checkIPAddr (dummy )
92
93
93
94
// Check collected parts of bridged networks.
94
- c .checkBridgedNetworks (prefix , l )
95
+ c .checkBridgedNetworks (prefixV46 . name , l )
95
96
}
96
97
}
97
98
@@ -126,7 +127,8 @@ func (c *spoc) checkIPAddr(n *network) {
126
127
ip := intf .ip
127
128
if other , found := ip2name [ip ]; found {
128
129
if ! (intf .redundant && redundant [other ]) {
129
- c .err ("Duplicate IP address for %s and %s" , other , intf )
130
+ c .err ("Duplicate IP address for %s and %s" ,
131
+ other , intf .vxName ())
130
132
}
131
133
} else {
132
134
ip2name [ip ] = intf .name
@@ -139,7 +141,7 @@ func (c *spoc) checkIPAddr(n *network) {
139
141
if shortIntf != nil && routeIntf != nil {
140
142
c .err ("Can't generate static routes for %s" +
141
143
" because IP address is unknown for:\n %s" ,
142
- routeIntf , shortIntf .nameList ())
144
+ routeIntf . vxName () , shortIntf .nameList ())
143
145
}
144
146
145
147
// Optimization: No need to collect .routeInZone at bridge router.
@@ -156,7 +158,7 @@ func (c *spoc) checkIPAddr(n *network) {
156
158
}
157
159
rg := h .ipRange
158
160
if other , found := range2name [rg ]; found {
159
- c .err ("Duplicate IP address for %s and %s" , other , h )
161
+ c .err ("Duplicate IP address for %s and %s" , other , h . vxName () )
160
162
} else {
161
163
range2name [rg ] = h .name
162
164
}
@@ -170,15 +172,15 @@ func (c *spoc) checkIPAddr(n *network) {
170
172
}
171
173
for ip , other := range ip2name {
172
174
if rg .Contains (ip ) {
173
- c .err ("Duplicate IP address for %s and %s" , other , h )
175
+ c .err ("Duplicate IP address for %s and %s" , other , h . vxName () )
174
176
}
175
177
}
176
178
}
177
179
178
180
for _ , h := range n .hosts {
179
181
if h .ip .IsValid () {
180
182
if other , found := ip2name [h .ip ]; found {
181
- c .err ("Duplicate IP address for %s and %s" , other , h )
183
+ c .err ("Duplicate IP address for %s and %s" , other , h . vxName () )
182
184
} else {
183
185
ip2name [h .ip ] = h .name
184
186
}
@@ -198,12 +200,12 @@ func (c *spoc) checkBridgedNetworks(prefix string, l netList) {
198
200
if n , found := c .symTable .network [prefix [len ("network:" ):]]; found {
199
201
c .err (
200
202
"Must not define %s together with bridged networks of same name" ,
201
- n )
203
+ n . vxName () )
202
204
}
203
205
n1 := l [0 ]
204
206
group := l [1 :]
205
207
if len (group ) == 0 {
206
- c .warn ("Bridged %s must not be used solitary" , n1 )
208
+ c .warn ("Bridged %s must not be used solitary" , n1 . vxName () )
207
209
}
208
210
seen := make (map [* router ]bool )
209
211
connected := make (map [* network ]bool )
@@ -214,7 +216,8 @@ func (c *spoc) checkBridgedNetworks(prefix string, l netList) {
214
216
n2 := next [0 ]
215
217
next = next [1 :]
216
218
if n1 .ipp != n2 .ipp {
217
- c .err ("%s and %s must have identical address" , n1 , n2 )
219
+ c .err ("%s and %s must have identical address" ,
220
+ n1 .vxName (), n2 .vxName ())
218
221
}
219
222
connected [n2 ] = true
220
223
for _ , in := range n2 .interfaces {
@@ -230,7 +233,7 @@ func (c *spoc) checkBridgedNetworks(prefix string, l netList) {
230
233
if l3 := in .layer3Intf ; l3 != nil {
231
234
if ! n1 .ipp .Contains (l3 .ip ) {
232
235
c .err ("%s's IP doesn't match address of bridged networks" ,
233
- l3 )
236
+ l3 . vxName () )
234
237
}
235
238
}
236
239
for _ , out := range r .interfaces {
@@ -246,7 +249,7 @@ func (c *spoc) checkBridgedNetworks(prefix string, l netList) {
246
249
}
247
250
for _ , n2 := range group {
248
251
if ! connected [n2 ] {
249
- c .err ("%s and %s must be connected by bridge" , n2 , n1 )
252
+ c .err ("%s and %s must be connected by bridge" , n2 . vxName () , n1 . vxName () )
250
253
}
251
254
}
252
255
}
0 commit comments