@@ -21,6 +21,7 @@ import (
21
21
"net"
22
22
"os"
23
23
"runtime"
24
+ "sort"
24
25
"syscall"
25
26
"time"
26
27
@@ -46,18 +47,19 @@ const defaultBrName = "cni0"
46
47
47
48
type NetConf struct {
48
49
types.NetConf
49
- BrName string `json:"bridge"`
50
- IsGW bool `json:"isGateway"`
51
- IsDefaultGW bool `json:"isDefaultGateway"`
52
- ForceAddress bool `json:"forceAddress"`
53
- IPMasq bool `json:"ipMasq"`
54
- MTU int `json:"mtu"`
55
- HairpinMode bool `json:"hairpinMode"`
56
- PromiscMode bool `json:"promiscMode"`
57
- Vlan int `json:"vlan"`
58
- PreserveDefaultVlan bool `json:"preserveDefaultVlan"`
59
- MacSpoofChk bool `json:"macspoofchk,omitempty"`
60
- EnableDad bool `json:"enabledad,omitempty"`
50
+ BrName string `json:"bridge"`
51
+ IsGW bool `json:"isGateway"`
52
+ IsDefaultGW bool `json:"isDefaultGateway"`
53
+ ForceAddress bool `json:"forceAddress"`
54
+ IPMasq bool `json:"ipMasq"`
55
+ MTU int `json:"mtu"`
56
+ HairpinMode bool `json:"hairpinMode"`
57
+ PromiscMode bool `json:"promiscMode"`
58
+ Vlan int `json:"vlan"`
59
+ VlanTrunk []* VlanTrunk `json:"vlanTrunk,omitempty"`
60
+ PreserveDefaultVlan bool `json:"preserveDefaultVlan"`
61
+ MacSpoofChk bool `json:"macspoofchk,omitempty"`
62
+ EnableDad bool `json:"enabledad,omitempty"`
61
63
62
64
Args struct {
63
65
Cni BridgeArgs `json:"cni,omitempty"`
@@ -66,7 +68,14 @@ type NetConf struct {
66
68
Mac string `json:"mac,omitempty"`
67
69
} `json:"runtimeConfig,omitempty"`
68
70
69
- mac string
71
+ mac string
72
+ vlans []int
73
+ }
74
+
75
+ type VlanTrunk struct {
76
+ MinID * int `json:"minID,omitempty"`
77
+ MaxID * int `json:"maxID,omitempty"`
78
+ ID * int `json:"id,omitempty"`
70
79
}
71
80
72
81
type BridgeArgs struct {
@@ -104,6 +113,17 @@ func loadNetConf(bytes []byte, envArgs string) (*NetConf, string, error) {
104
113
if n .Vlan < 0 || n .Vlan > 4094 {
105
114
return nil , "" , fmt .Errorf ("invalid VLAN ID %d (must be between 0 and 4094)" , n .Vlan )
106
115
}
116
+ var err error
117
+ n .vlans , err = collectVlanTrunk (n .VlanTrunk )
118
+ if err != nil {
119
+ // fail to parsing
120
+ return nil , "" , err
121
+ }
122
+
123
+ // Currently bridge CNI only support access port(untagged only) or trunk port(tagged only)
124
+ if n .Vlan > 0 && n .vlans != nil {
125
+ return nil , "" , errors .New ("cannot set vlan and vlanTrunk at the same time" )
126
+ }
107
127
108
128
if envArgs != "" {
109
129
e := MacEnvArgs {}
@@ -127,6 +147,61 @@ func loadNetConf(bytes []byte, envArgs string) (*NetConf, string, error) {
127
147
return n , n .CNIVersion , nil
128
148
}
129
149
150
+ // This method is copied from https://github.com/k8snetworkplumbingwg/ovs-cni/blob/v0.27.2/pkg/plugin/plugin.go
151
+ func collectVlanTrunk (vlanTrunk []* VlanTrunk ) ([]int , error ) {
152
+ if vlanTrunk == nil {
153
+ return nil , nil
154
+ }
155
+
156
+ vlanMap := make (map [int ]struct {})
157
+ for _ , item := range vlanTrunk {
158
+ var minID int
159
+ var maxID int
160
+ var ID int
161
+
162
+ switch {
163
+ case item .MinID != nil && item .MaxID != nil :
164
+ minID = * item .MinID
165
+ if minID <= 0 || minID > 4094 {
166
+ return nil , errors .New ("incorrect trunk minID parameter" )
167
+ }
168
+ maxID = * item .MaxID
169
+ if maxID <= 0 || maxID > 4094 {
170
+ return nil , errors .New ("incorrect trunk maxID parameter" )
171
+ }
172
+ if maxID < minID {
173
+ return nil , errors .New ("minID is greater than maxID in trunk parameter" )
174
+ }
175
+ for v := minID ; v <= maxID ; v ++ {
176
+ vlanMap [v ] = struct {}{}
177
+ }
178
+ case item .MinID == nil && item .MaxID != nil :
179
+ return nil , errors .New ("minID and maxID should be configured simultaneously, minID is missing" )
180
+ case item .MinID != nil && item .MaxID == nil :
181
+ return nil , errors .New ("minID and maxID should be configured simultaneously, maxID is missing" )
182
+ }
183
+
184
+ // single vid
185
+ if item .ID != nil {
186
+ ID = * item .ID
187
+ if ID <= 0 || ID > 4094 {
188
+ return nil , errors .New ("incorrect trunk id parameter" )
189
+ }
190
+ vlanMap [ID ] = struct {}{}
191
+ }
192
+ }
193
+
194
+ if len (vlanMap ) == 0 {
195
+ return nil , nil
196
+ }
197
+ vlans := make ([]int , 0 , len (vlanMap ))
198
+ for k := range vlanMap {
199
+ vlans = append (vlans , k )
200
+ }
201
+ sort .Slice (vlans , func (i int , j int ) bool { return vlans [i ] < vlans [j ] })
202
+ return vlans , nil
203
+ }
204
+
130
205
// calcGateways processes the results from the IPAM plugin and does the
131
206
// following for each IP family:
132
207
// - Calculates and compiles a list of gateway addresses
@@ -316,7 +391,7 @@ func ensureVlanInterface(br *netlink.Bridge, vlanID int, preserveDefaultVlan boo
316
391
return nil , fmt .Errorf ("faild to find host namespace: %v" , err )
317
392
}
318
393
319
- _ , brGatewayIface , err := setupVeth (hostNS , br , name , br .MTU , false , vlanID , preserveDefaultVlan , "" )
394
+ _ , brGatewayIface , err := setupVeth (hostNS , br , name , br .MTU , false , vlanID , nil , preserveDefaultVlan , "" )
320
395
if err != nil {
321
396
return nil , fmt .Errorf ("faild to create vlan gateway %q: %v" , name , err )
322
397
}
@@ -335,7 +410,7 @@ func ensureVlanInterface(br *netlink.Bridge, vlanID int, preserveDefaultVlan boo
335
410
return brGatewayVeth , nil
336
411
}
337
412
338
- func setupVeth (netns ns.NetNS , br * netlink.Bridge , ifName string , mtu int , hairpinMode bool , vlanID int , preserveDefaultVlan bool , mac string ) (* current.Interface , * current.Interface , error ) {
413
+ func setupVeth (netns ns.NetNS , br * netlink.Bridge , ifName string , mtu int , hairpinMode bool , vlanID int , vlans [] int , preserveDefaultVlan bool , mac string ) (* current.Interface , * current.Interface , error ) {
339
414
contIface := & current.Interface {}
340
415
hostIface := & current.Interface {}
341
416
@@ -372,20 +447,28 @@ func setupVeth(netns ns.NetNS, br *netlink.Bridge, ifName string, mtu int, hairp
372
447
return nil , nil , fmt .Errorf ("failed to setup hairpin mode for %v: %v" , hostVeth .Attrs ().Name , err )
373
448
}
374
449
375
- if vlanID != 0 {
376
- if ! preserveDefaultVlan {
377
- err = removeDefaultVlan (hostVeth )
378
- if err != nil {
379
- return nil , nil , fmt .Errorf ("failed to remove default vlan on interface %q: %v" , hostIface .Name , err )
380
- }
450
+ if (vlanID != 0 || len (vlans ) > 0 ) && ! preserveDefaultVlan {
451
+ err = removeDefaultVlan (hostVeth )
452
+ if err != nil {
453
+ return nil , nil , fmt .Errorf ("failed to remove default vlan on interface %q: %v" , hostIface .Name , err )
381
454
}
455
+ }
382
456
457
+ // Currently bridge CNI only support access port(untagged only) or trunk port(tagged only)
458
+ if vlanID != 0 {
383
459
err = netlink .BridgeVlanAdd (hostVeth , uint16 (vlanID ), true , true , false , true )
384
460
if err != nil {
385
461
return nil , nil , fmt .Errorf ("failed to setup vlan tag on interface %q: %v" , hostIface .Name , err )
386
462
}
387
463
}
388
464
465
+ for _ , v := range vlans {
466
+ err = netlink .BridgeVlanAdd (hostVeth , uint16 (v ), false , false , false , true )
467
+ if err != nil {
468
+ return nil , nil , fmt .Errorf ("failed to setup vlan tag on interface %q: %w" , hostIface .Name , err )
469
+ }
470
+ }
471
+
389
472
return hostIface , contIface , nil
390
473
}
391
474
@@ -414,7 +497,10 @@ func calcGatewayIP(ipn *net.IPNet) net.IP {
414
497
}
415
498
416
499
func setupBridge (n * NetConf ) (* netlink.Bridge , * current.Interface , error ) {
417
- vlanFiltering := n .Vlan != 0
500
+ vlanFiltering := false
501
+ if n .Vlan != 0 || n .VlanTrunk != nil {
502
+ vlanFiltering = true
503
+ }
418
504
// create bridge if necessary
419
505
br , err := ensureBridge (n .BrName , n .MTU , n .PromiscMode , vlanFiltering )
420
506
if err != nil {
@@ -463,7 +549,7 @@ func cmdAdd(args *skel.CmdArgs) error {
463
549
}
464
550
defer netns .Close ()
465
551
466
- hostInterface , containerInterface , err := setupVeth (netns , br , args .IfName , n .MTU , n .HairpinMode , n .Vlan , n .PreserveDefaultVlan , n .mac )
552
+ hostInterface , containerInterface , err := setupVeth (netns , br , args .IfName , n .MTU , n .HairpinMode , n .Vlan , n .vlans , n . PreserveDefaultVlan , n .mac )
467
553
if err != nil {
468
554
return err
469
555
}
0 commit comments