@@ -7,6 +7,11 @@ import (
77 "github.com/docker/libcontainer/netlink"
88)
99
10+ // Default MacVlan mode
11+ const (
12+ default_mode = "bridge"
13+ )
14+
1015// Supported macvlan modes by tenus package
1116var MacVlanModes = map [string ]bool {
1217 "private" : true ,
@@ -17,7 +22,7 @@ var MacVlanModes = map[string]bool{
1722// MacVlanOptions allows you to specify some options for macvlan link.
1823type MacVlanOptions struct {
1924 // macvlan device name
20- MacVlanDev string
25+ Dev string
2126 // macvlan mode
2227 Mode string
2328 // MAC address
@@ -47,13 +52,12 @@ type MacVlanLink struct {
4752// NewMacVlanLink creates macvlan network link
4853//
4954// It is equivalent of running:
50- // ip link add name mc${RANDOM STRING} link ${master interface} type macvlan mode ${mode}
55+ // ip link add name mc${RANDOM STRING} link ${master interface} type macvlan
5156// NewMacVlanLink returns MacVlaner which is initialized to a pointer of type MacVlanLink if the
5257// macvlan link was created successfully on the Linux host. Newly created link is assigned
53- // a random name starting with "mc". It sets the macvlan mode the parameter passed as argument.
54- // If incorrect network mode is passed as a paramter, it sets the macvlan mode to "bridge".
58+ // a random name starting with "mc". It sets the macvlan mode to "bridge" mode which is a default.
5559// It returns error if the link could not be created.
56- func NewMacVlanLink (masterDev string , mode string ) (MacVlaner , error ) {
60+ func NewMacVlanLink (masterDev string ) (MacVlaner , error ) {
5761 macVlanDev := makeNetInterfaceName ("mc" )
5862
5963 if ok , err := NetInterfaceNameValid (masterDev ); ! ok {
@@ -64,15 +68,7 @@ func NewMacVlanLink(masterDev string, mode string) (MacVlaner, error) {
6468 return nil , fmt .Errorf ("Master MAC VLAN device %s does not exist on the host" , masterDev )
6569 }
6670
67- if mode != "" {
68- if _ , ok := MacVlanModes [mode ]; ! ok {
69- return nil , fmt .Errorf ("Unsupported MacVlan mode specified: %s" , mode )
70- }
71- } else {
72- mode = "bridge"
73- }
74-
75- if err := netlink .NetworkLinkAddMacVlan (masterDev , macVlanDev , mode ); err != nil {
71+ if err := netlink .NetworkLinkAddMacVlan (masterDev , macVlanDev , default_mode ); err != nil {
7672 return nil , err
7773 }
7874
@@ -91,7 +87,7 @@ func NewMacVlanLink(masterDev string, mode string) (MacVlaner, error) {
9187 ifc : macVlanIfc ,
9288 },
9389 masterIfc : masterIfc ,
94- mode : mode ,
90+ mode : default_mode ,
9591 }, nil
9692}
9793
@@ -101,12 +97,9 @@ func NewMacVlanLink(masterDev string, mode string) (MacVlaner, error) {
10197// It is equivalent of running:
10298// ip link add name ${macvlan name} link ${master interface} address ${macaddress} type macvlan mode ${mode}
10399// NewMacVlanLinkWithOptions returns MacVlaner which is initialized to a pointer of type MacVlanLink if the
104- // macvlan link was created successfully on the Linux host. It returns error if the macvlan link could not be created.
100+ // macvlan link was created successfully on the Linux host. If particular option is empty, it sets default value if possible.
101+ // It returns error if the macvlan link could not be created or if incorrect options have been passed.
105102func NewMacVlanLinkWithOptions (masterDev string , opts MacVlanOptions ) (MacVlaner , error ) {
106- macVlanDev := opts .MacVlanDev
107- mode := opts .Mode
108- macaddr := opts .MacAddr
109-
110103 if ok , err := NetInterfaceNameValid (masterDev ); ! ok {
111104 return nil , err
112105 }
@@ -115,42 +108,23 @@ func NewMacVlanLinkWithOptions(masterDev string, opts MacVlanOptions) (MacVlaner
115108 return nil , fmt .Errorf ("Master MAC VLAN device %s does not exist on the host" , masterDev )
116109 }
117110
118- if macVlanDev != "" {
119- if ok , err := NetInterfaceNameValid (macVlanDev ); ! ok {
120- return nil , err
121- }
122-
123- if _ , err := net .InterfaceByName (macVlanDev ); err == nil {
124- return nil , fmt .Errorf ("MAC VLAN device %s already assigned on the host" , macVlanDev )
125- }
126- } else {
127- macVlanDev = makeNetInterfaceName ("mc" )
128- }
129-
130- if mode != "" {
131- if _ , ok := MacVlanModes [mode ]; ! ok {
132- return nil , fmt .Errorf ("Unsupported MacVlan mode specified: %s" , mode )
133- }
134- } else {
135- mode = "bridge"
111+ if err := validateMacVlanOptions (& opts ); err != nil {
112+ return nil , err
136113 }
137114
138- if err := netlink .NetworkLinkAddMacVlan (masterDev , macVlanDev , opts .Mode ); err != nil {
115+ if err := netlink .NetworkLinkAddMacVlan (masterDev , opts . Dev , opts .Mode ); err != nil {
139116 return nil , err
140117 }
141118
142- macVlanIfc , err := net .InterfaceByName (macVlanDev )
119+ macVlanIfc , err := net .InterfaceByName (opts . Dev )
143120 if err != nil {
144121 return nil , fmt .Errorf ("Could not find the new interface: %s" , err )
145122 }
146123
147- if macaddr != "" {
148- if _ , err = net .ParseMAC (macaddr ); err == nil {
149- if err := netlink .NetworkSetMacAddress (macVlanIfc , macaddr ); err != nil {
150- if errDel := DeleteLink (macVlanIfc .Name ); err != nil {
151- return nil , fmt .Errorf ("Incorrect options specified. Attempt to delete the link failed: %s" ,
152- errDel )
153- }
124+ if opts .MacAddr != "" {
125+ if err := netlink .NetworkSetMacAddress (macVlanIfc , opts .MacAddr ); err != nil {
126+ if errDel := DeleteLink (macVlanIfc .Name ); errDel != nil {
127+ return nil , fmt .Errorf ("Incorrect options specified. Attempt to delete the link failed: %s" , errDel )
154128 }
155129 }
156130 }
@@ -165,7 +139,7 @@ func NewMacVlanLinkWithOptions(masterDev string, opts MacVlanOptions) (MacVlaner
165139 ifc : macVlanIfc ,
166140 },
167141 masterIfc : masterIfc ,
168- mode : mode ,
142+ mode : opts . Mode ,
169143 }, nil
170144}
171145
@@ -183,3 +157,33 @@ func (macvln *MacVlanLink) MasterNetInterface() *net.Interface {
183157func (macvln * MacVlanLink ) Mode () string {
184158 return macvln .mode
185159}
160+
161+ func validateMacVlanOptions (opts * MacVlanOptions ) error {
162+ if opts .Dev != "" {
163+ if ok , err := NetInterfaceNameValid (opts .Dev ); ! ok {
164+ return err
165+ }
166+
167+ if _ , err := net .InterfaceByName (opts .Dev ); err == nil {
168+ return fmt .Errorf ("MAC VLAN device %s already assigned on the host" , opts .Dev )
169+ }
170+ } else {
171+ opts .Dev = makeNetInterfaceName ("mc" )
172+ }
173+
174+ if opts .Mode != "" {
175+ if _ , ok := MacVlanModes [opts .Mode ]; ! ok {
176+ return fmt .Errorf ("Unsupported MacVlan mode specified: %s" , opts .Mode )
177+ }
178+ } else {
179+ opts .Mode = default_mode
180+ }
181+
182+ if opts .MacAddr != "" {
183+ if _ , err := net .ParseMAC (opts .MacAddr ); err == nil {
184+ return fmt .Errorf ("Incorrect MAC ADDRESS specified: %s" , opts .MacAddr )
185+ }
186+ }
187+
188+ return nil
189+ }
0 commit comments