Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lxc
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
lxc
Commits
ea84ddf9
Unverified
Commit
ea84ddf9
authored
May 01, 2019
by
Christian Brauner
Committed by
GitHub
May 01, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2950 from tomponline/tp-ipvlan
network: Adds IPVLAN support
parents
28805eb0
c9f52382
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
545 additions
and
15 deletions
+545
-15
api-extensions.md
doc/api-extensions.md
+14
-0
lxc.container.conf.sgml.in
doc/lxc.container.conf.sgml.in
+42
-7
api_extensions.h
src/lxc/api_extensions.h
+1
-0
confile.c
src/lxc/confile.c
+167
-8
confile_utils.c
src/lxc/confile_utils.c
+79
-0
confile_utils.h
src/lxc/confile_utils.h
+4
-0
macro.h
src/lxc/macro.h
+32
-0
network.c
src/lxc/network.c
+164
-0
network.h
src/lxc/network.h
+7
-0
parse_config_file.c
src/tests/parse_config_file.c
+35
-0
No files found.
doc/api-extensions.md
View file @
ea84ddf9
...
@@ -51,3 +51,17 @@ The caller can read this message, inspect the syscalls including its arguments.
...
@@ -51,3 +51,17 @@ The caller can read this message, inspect the syscalls including its arguments.
This introduces the
`lxc.net.[i].veth.ipv4.route`
and
`lxc.net.[i].veth.ipv6.route`
properties
This introduces the
`lxc.net.[i].veth.ipv4.route`
and
`lxc.net.[i].veth.ipv6.route`
properties
on
`veth`
type network interfaces. This allows adding static routes on host to the container's
on
`veth`
type network interfaces. This allows adding static routes on host to the container's
network interface.
network interface.
## network\_ipvlan
This introduces the
`ipvlan`
network type.
Example usage:
```
lxc.net[i].type=ipvlan
lxc.net[i].ipvlan.mode=[l3|l3s|l2] (defaults to l3)
lxc.net[i].ipvlan.isolation=[bridge|private|vepa] (defaults to bridge)
lxc.net[i].link=eth0
lxc.net[i].flags=up
```
doc/lxc.container.conf.sgml.in
View file @
ea84ddf9
...
@@ -485,7 +485,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
...
@@ -485,7 +485,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
different macvlan on the same upper device. The accepted
different macvlan on the same upper device. The accepted
modes are <option>private</option>, <option>vepa</option>,
modes are <option>private</option>, <option>vepa</option>,
<option>bridge</option> and <option>passthru</option>.
<option>bridge</option> and <option>passthru</option>.
In <option>private</option> mode, the device never
In <option>private</option> mode, the device never
communicates with any other device on the same upper_dev (default).
communicates with any other device on the same upper_dev (default).
In <option>vepa</option> mode, the new Virtual Ethernet Port
In <option>vepa</option> mode, the new Virtual Ethernet Port
Aggregator (VEPA) mode, it assumes that the adjacent
Aggregator (VEPA) mode, it assumes that the adjacent
...
@@ -511,6 +511,41 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
...
@@ -511,6 +511,41 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
</para>
</para>
<para>
<para>
<option>ipvlan:</option> an ipvlan interface is linked
with the interface specified by
the <option>lxc.net.[i].link</option> and assigned to
the container.
<option>lxc.net.[i].ipvlan.mode</option> specifies the
mode the ipvlan will use to communicate between
different ipvlan on the same upper device. The accepted
modes are <option>l3</option>, <option>l3s</option> and
<option>l2</option>. It defaults to <option>l3</option> mode.
In <option>l3</option> mode TX processing up to L3 happens on the stack instance
attached to the slave device and packets are switched to the stack instance of the
master device for the L2 processing and routing from that instance will be
used before packets are queued on the outbound device. In this mode the slaves
will not receive nor can send multicast / broadcast traffic.
In <option>l3s</option> mode TX processing is very similar to the L3 mode except that
iptables (conn-tracking) works in this mode and hence it is L3-symmetric (L3s).
This will have slightly less performance but that shouldn't matter since you are
choosing this mode over plain-L3 mode to make conn-tracking work.
In <option>l2</option> mode TX processing happens on the stack instance attached to
the slave device and packets are switched and queued to the master device to send
out. In this mode the slaves will RX/TX multicast and broadcast (if applicable) as well.
<option>lxc.net.[i].ipvlan.isolation</option> specifies the isolation mode.
The accepted isolation values are <option>bridge</option>,
<option>private</option> and <option>vepa</option>.
It defaults to <option>bridge</option>.
In <option>bridge</option> isolation mode slaves can cross-talk among themselves
apart from talking through the master device.
In <option>private</option> isolation mode the port is set in private mode.
i.e. port won't allow cross communication between slaves.
In <option>vepa</option> isolation mode the port is set in VEPA mode.
i.e. port will offload switching functionality to the external entity as
described in 802.1Qbg.
</para>
<para>
<option>phys:</option> an already existing interface
<option>phys:</option> an already existing interface
specified by the <option>lxc.net.[i].link</option> is
specified by the <option>lxc.net.[i].link</option> is
assigned to the container.
assigned to the container.
...
@@ -610,8 +645,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
...
@@ -610,8 +645,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
interface (as specified by the
interface (as specified by the
<option>lxc.net.[i].link</option> option) and use that as
<option>lxc.net.[i].link</option> option) and use that as
the gateway. <option>auto</option> is only available when
the gateway. <option>auto</option> is only available when
using the <option>veth</option>
and
using the <option>veth</option>
,
<option>macvlan</option> network types.
<option>macvlan</option>
and <option>ipvlan</option>
network types.
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
...
@@ -644,8 +679,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
...
@@ -644,8 +679,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
interface (as specified by the
interface (as specified by the
<option>lxc.net.[i].link</option> option) and use that as
<option>lxc.net.[i].link</option> option) and use that as
the gateway. <option>auto</option> is only available when
the gateway. <option>auto</option> is only available when
using the <option>veth</option>
and
using the <option>veth</option>
,
<option>macvlan</option> network types.
<option>macvlan</option>
and <option>ipvlan</option>
network types.
</para>
</para>
</listitem>
</listitem>
</varlistentry>
</varlistentry>
...
@@ -680,7 +715,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
...
@@ -680,7 +715,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<listitem>
<listitem>
<para>
<para>
LXC_NET_TYPE: the network type. This is one of the valid
LXC_NET_TYPE: the network type. This is one of the valid
network types listed here (e.g. '
mac
vlan', 'veth').
network types listed here (e.g. '
vlan', 'macvlan', 'ip
vlan', 'veth').
</para>
</para>
</listitem>
</listitem>
...
@@ -746,7 +781,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
...
@@ -746,7 +781,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<listitem>
<listitem>
<para>
<para>
LXC_NET_TYPE: the network type. This is one of the valid
LXC_NET_TYPE: the network type. This is one of the valid
network types listed here (e.g. '
mac
vlan', 'veth').
network types listed here (e.g. '
vlan', 'macvlan', 'ip
vlan', 'veth').
</para>
</para>
</listitem>
</listitem>
...
...
src/lxc/api_extensions.h
View file @
ea84ddf9
...
@@ -45,6 +45,7 @@ static char *api_extensions[] = {
...
@@ -45,6 +45,7 @@ static char *api_extensions[] = {
"seccomp_allow_nesting"
,
"seccomp_allow_nesting"
,
"seccomp_notify"
,
"seccomp_notify"
,
"network_veth_routes"
,
"network_veth_routes"
,
"network_ipvlan"
,
};
};
static
size_t
nr_api_extensions
=
sizeof
(
api_extensions
)
/
sizeof
(
*
api_extensions
);
static
size_t
nr_api_extensions
=
sizeof
(
api_extensions
)
/
sizeof
(
*
api_extensions
);
...
...
src/lxc/confile.c
View file @
ea84ddf9
...
@@ -130,6 +130,8 @@ lxc_config_define(net_ipv6_address);
...
@@ -130,6 +130,8 @@ lxc_config_define(net_ipv6_address);
lxc_config_define
(
net_ipv6_gateway
);
lxc_config_define
(
net_ipv6_gateway
);
lxc_config_define
(
net_link
);
lxc_config_define
(
net_link
);
lxc_config_define
(
net_macvlan_mode
);
lxc_config_define
(
net_macvlan_mode
);
lxc_config_define
(
net_ipvlan_mode
);
lxc_config_define
(
net_ipvlan_isolation
);
lxc_config_define
(
net_mtu
);
lxc_config_define
(
net_mtu
);
lxc_config_define
(
net_name
);
lxc_config_define
(
net_name
);
lxc_config_define
(
net_nic
);
lxc_config_define
(
net_nic
);
...
@@ -221,6 +223,8 @@ static struct lxc_config_t config_jump_table[] = {
...
@@ -221,6 +223,8 @@ static struct lxc_config_t config_jump_table[] = {
{
"lxc.net.ipv6.gateway"
,
set_config_net_ipv6_gateway
,
get_config_net_ipv6_gateway
,
clr_config_net_ipv6_gateway
,
},
{
"lxc.net.ipv6.gateway"
,
set_config_net_ipv6_gateway
,
get_config_net_ipv6_gateway
,
clr_config_net_ipv6_gateway
,
},
{
"lxc.net.link"
,
set_config_net_link
,
get_config_net_link
,
clr_config_net_link
,
},
{
"lxc.net.link"
,
set_config_net_link
,
get_config_net_link
,
clr_config_net_link
,
},
{
"lxc.net.macvlan.mode"
,
set_config_net_macvlan_mode
,
get_config_net_macvlan_mode
,
clr_config_net_macvlan_mode
,
},
{
"lxc.net.macvlan.mode"
,
set_config_net_macvlan_mode
,
get_config_net_macvlan_mode
,
clr_config_net_macvlan_mode
,
},
{
"lxc.net.ipvlan.mode"
,
set_config_net_ipvlan_mode
,
get_config_net_ipvlan_mode
,
clr_config_net_ipvlan_mode
,
},
{
"lxc.net.ipvlan.isolation"
,
set_config_net_ipvlan_isolation
,
get_config_net_ipvlan_isolation
,
clr_config_net_ipvlan_isolation
,
},
{
"lxc.net.mtu"
,
set_config_net_mtu
,
get_config_net_mtu
,
clr_config_net_mtu
,
},
{
"lxc.net.mtu"
,
set_config_net_mtu
,
get_config_net_mtu
,
clr_config_net_mtu
,
},
{
"lxc.net.name"
,
set_config_net_name
,
get_config_net_name
,
clr_config_net_name
,
},
{
"lxc.net.name"
,
set_config_net_name
,
get_config_net_name
,
clr_config_net_name
,
},
{
"lxc.net.script.down"
,
set_config_net_script_down
,
get_config_net_script_down
,
clr_config_net_script_down
,
},
{
"lxc.net.script.down"
,
set_config_net_script_down
,
get_config_net_script_down
,
clr_config_net_script_down
,
},
...
@@ -291,21 +295,24 @@ static int set_config_net_type(const char *key, const char *value,
...
@@ -291,21 +295,24 @@ static int set_config_net_type(const char *key, const char *value,
if
(
!
netdev
)
if
(
!
netdev
)
return
-
1
;
return
-
1
;
if
(
!
strcmp
(
value
,
"veth"
)
)
{
if
(
strcmp
(
value
,
"veth"
)
==
0
)
{
netdev
->
type
=
LXC_NET_VETH
;
netdev
->
type
=
LXC_NET_VETH
;
lxc_list_init
(
&
netdev
->
priv
.
veth_attr
.
ipv4_routes
);
lxc_list_init
(
&
netdev
->
priv
.
veth_attr
.
ipv4_routes
);
lxc_list_init
(
&
netdev
->
priv
.
veth_attr
.
ipv6_routes
);
lxc_list_init
(
&
netdev
->
priv
.
veth_attr
.
ipv6_routes
);
}
else
if
(
!
strcmp
(
value
,
"macvlan"
)
)
{
}
else
if
(
strcmp
(
value
,
"macvlan"
)
==
0
)
{
netdev
->
type
=
LXC_NET_MACVLAN
;
netdev
->
type
=
LXC_NET_MACVLAN
;
lxc_macvlan_mode_to_flag
(
&
netdev
->
priv
.
macvlan_attr
.
mode
,
lxc_macvlan_mode_to_flag
(
&
netdev
->
priv
.
macvlan_attr
.
mode
,
"private"
);
"private"
);
}
else
if
(
strcmp
(
value
,
"ipvlan"
)
==
0
)
{
}
else
if
(
!
strcmp
(
value
,
"vlan"
))
{
netdev
->
type
=
LXC_NET_IPVLAN
;
lxc_ipvlan_mode_to_flag
(
&
netdev
->
priv
.
ipvlan_attr
.
mode
,
"l3"
);
lxc_ipvlan_isolation_to_flag
(
&
netdev
->
priv
.
ipvlan_attr
.
isolation
,
"bridge"
);
}
else
if
(
strcmp
(
value
,
"vlan"
)
==
0
)
{
netdev
->
type
=
LXC_NET_VLAN
;
netdev
->
type
=
LXC_NET_VLAN
;
}
else
if
(
!
strcmp
(
value
,
"phys"
)
)
{
}
else
if
(
strcmp
(
value
,
"phys"
)
==
0
)
{
netdev
->
type
=
LXC_NET_PHYS
;
netdev
->
type
=
LXC_NET_PHYS
;
}
else
if
(
!
strcmp
(
value
,
"empty"
)
)
{
}
else
if
(
strcmp
(
value
,
"empty"
)
==
0
)
{
netdev
->
type
=
LXC_NET_EMPTY
;
netdev
->
type
=
LXC_NET_EMPTY
;
}
else
if
(
!
strcmp
(
value
,
"none"
)
)
{
}
else
if
(
strcmp
(
value
,
"none"
)
==
0
)
{
netdev
->
type
=
LXC_NET_NONE
;
netdev
->
type
=
LXC_NET_NONE
;
}
else
{
}
else
{
ERROR
(
"Invalid network type %s"
,
value
);
ERROR
(
"Invalid network type %s"
,
value
);
...
@@ -438,6 +445,44 @@ static int set_config_net_macvlan_mode(const char *key, const char *value,
...
@@ -438,6 +445,44 @@ static int set_config_net_macvlan_mode(const char *key, const char *value,
return
lxc_macvlan_mode_to_flag
(
&
netdev
->
priv
.
macvlan_attr
.
mode
,
value
);
return
lxc_macvlan_mode_to_flag
(
&
netdev
->
priv
.
macvlan_attr
.
mode
,
value
);
}
}
static
int
set_config_net_ipvlan_mode
(
const
char
*
key
,
const
char
*
value
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
struct
lxc_netdev
*
netdev
=
data
;
if
(
lxc_config_value_empty
(
value
))
return
clr_config_net_ipvlan_mode
(
key
,
lxc_conf
,
data
);
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_IPVLAN
)
{
SYSERROR
(
"Invalid ipvlan mode
\"
%s
\"
, can only be used with ipvlan network"
,
value
);
return
minus_one_set_errno
(
EINVAL
);
}
return
lxc_ipvlan_mode_to_flag
(
&
netdev
->
priv
.
ipvlan_attr
.
mode
,
value
);
}
static
int
set_config_net_ipvlan_isolation
(
const
char
*
key
,
const
char
*
value
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
struct
lxc_netdev
*
netdev
=
data
;
if
(
lxc_config_value_empty
(
value
))
return
clr_config_net_ipvlan_isolation
(
key
,
lxc_conf
,
data
);
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_IPVLAN
)
{
SYSERROR
(
"Invalid ipvlan isolation
\"
%s
\"
, can only be used with ipvlan network"
,
value
);
return
minus_one_set_errno
(
EINVAL
);
}
return
lxc_ipvlan_isolation_to_flag
(
&
netdev
->
priv
.
ipvlan_attr
.
isolation
,
value
);
}
static
int
set_config_net_hwaddr
(
const
char
*
key
,
const
char
*
value
,
static
int
set_config_net_hwaddr
(
const
char
*
key
,
const
char
*
value
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
{
...
@@ -4931,6 +4976,38 @@ static int clr_config_net_macvlan_mode(const char *key,
...
@@ -4931,6 +4976,38 @@ static int clr_config_net_macvlan_mode(const char *key,
return
0
;
return
0
;
}
}
static
int
clr_config_net_ipvlan_mode
(
const
char
*
key
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
struct
lxc_netdev
*
netdev
=
data
;
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_IPVLAN
)
return
0
;
netdev
->
priv
.
ipvlan_attr
.
mode
=
-
1
;
return
0
;
}
static
int
clr_config_net_ipvlan_isolation
(
const
char
*
key
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
struct
lxc_netdev
*
netdev
=
data
;
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_IPVLAN
)
return
0
;
netdev
->
priv
.
ipvlan_attr
.
isolation
=
-
1
;
return
0
;
}
static
int
clr_config_net_veth_pair
(
const
char
*
key
,
struct
lxc_conf
*
lxc_conf
,
static
int
clr_config_net_veth_pair
(
const
char
*
key
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
void
*
data
)
{
{
...
@@ -5268,6 +5345,84 @@ static int get_config_net_macvlan_mode(const char *key, char *retv, int inlen,
...
@@ -5268,6 +5345,84 @@ static int get_config_net_macvlan_mode(const char *key, char *retv, int inlen,
return
fulllen
;
return
fulllen
;
}
}
static
int
get_config_net_ipvlan_mode
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
struct
lxc_conf
*
c
,
void
*
data
)
{
int
len
;
int
fulllen
=
0
;
const
char
*
mode
;
struct
lxc_netdev
*
netdev
=
data
;
if
(
!
retv
)
inlen
=
0
;
else
memset
(
retv
,
0
,
inlen
);
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_IPVLAN
)
return
0
;
switch
(
netdev
->
priv
.
ipvlan_attr
.
mode
)
{
case
IPVLAN_MODE_L3
:
mode
=
"l3"
;
break
;
case
IPVLAN_MODE_L3S
:
mode
=
"l3s"
;
break
;
case
IPVLAN_MODE_L2
:
mode
=
"l2"
;
break
;
default:
mode
=
"(invalid)"
;
break
;
}
strprint
(
retv
,
inlen
,
"%s"
,
mode
);
return
fulllen
;
}
static
int
get_config_net_ipvlan_isolation
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
struct
lxc_conf
*
c
,
void
*
data
)
{
int
len
;
int
fulllen
=
0
;
const
char
*
mode
;
struct
lxc_netdev
*
netdev
=
data
;
if
(
!
retv
)
inlen
=
0
;
else
memset
(
retv
,
0
,
inlen
);
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_IPVLAN
)
return
0
;
switch
(
netdev
->
priv
.
ipvlan_attr
.
isolation
)
{
case
IPVLAN_ISOLATION_BRIDGE
:
mode
=
"bridge"
;
break
;
case
IPVLAN_ISOLATION_PRIVATE
:
mode
=
"private"
;
break
;
case
IPVLAN_ISOLATION_VEPA
:
mode
=
"vepa"
;
break
;
default:
mode
=
"(invalid)"
;
break
;
}
strprint
(
retv
,
inlen
,
"%s"
,
mode
);
return
fulllen
;
}
static
int
get_config_net_veth_pair
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
static
int
get_config_net_veth_pair
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
struct
lxc_conf
*
c
,
void
*
data
)
struct
lxc_conf
*
c
,
void
*
data
)
{
{
...
@@ -5718,6 +5873,10 @@ int lxc_list_net(struct lxc_conf *c, const char *key, char *retv, int inlen)
...
@@ -5718,6 +5873,10 @@ int lxc_list_net(struct lxc_conf *c, const char *key, char *retv, int inlen)
case
LXC_NET_MACVLAN
:
case
LXC_NET_MACVLAN
:
strprint
(
retv
,
inlen
,
"macvlan.mode
\n
"
);
strprint
(
retv
,
inlen
,
"macvlan.mode
\n
"
);
break
;
break
;
case
LXC_NET_IPVLAN
:
strprint
(
retv
,
inlen
,
"ipvlan.mode
\n
"
);
strprint
(
retv
,
inlen
,
"ipvlan.isolation
\n
"
);
break
;
case
LXC_NET_VLAN
:
case
LXC_NET_VLAN
:
strprint
(
retv
,
inlen
,
"vlan.id
\n
"
);
strprint
(
retv
,
inlen
,
"vlan.id
\n
"
);
break
;
break
;
...
...
src/lxc/confile_utils.c
View file @
ea84ddf9
...
@@ -299,6 +299,17 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
...
@@ -299,6 +299,17 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
mode
?
mode
:
"(invalid mode)"
);
mode
?
mode
:
"(invalid mode)"
);
}
}
break
;
break
;
case
LXC_NET_IPVLAN
:
TRACE
(
"type: ipvlan"
);
char
*
mode
;
mode
=
lxc_ipvlan_flag_to_mode
(
netdev
->
priv
.
ipvlan_attr
.
mode
);
TRACE
(
"ipvlan mode: %s"
,
mode
?
mode
:
"(invalid mode)"
);
char
*
isolation
;
isolation
=
lxc_ipvlan_flag_to_isolation
(
netdev
->
priv
.
ipvlan_attr
.
isolation
);
TRACE
(
"ipvlan isolation: %s"
,
isolation
?
isolation
:
"(invalid isolation)"
);
break
;
case
LXC_NET_VLAN
:
case
LXC_NET_VLAN
:
TRACE
(
"type: vlan"
);
TRACE
(
"type: vlan"
);
TRACE
(
"vlan id: %d"
,
netdev
->
priv
.
vlan_attr
.
vid
);
TRACE
(
"vlan id: %d"
,
netdev
->
priv
.
vlan_attr
.
vid
);
...
@@ -519,6 +530,74 @@ char *lxc_macvlan_flag_to_mode(int mode)
...
@@ -519,6 +530,74 @@ char *lxc_macvlan_flag_to_mode(int mode)
return
NULL
;
return
NULL
;
}
}
static
struct
lxc_ipvlan_mode
{
char
*
name
;
int
mode
;
}
ipvlan_mode
[]
=
{
{
"l3"
,
IPVLAN_MODE_L3
},
{
"l3s"
,
IPVLAN_MODE_L3S
},
{
"l2"
,
IPVLAN_MODE_L2
},
};
int
lxc_ipvlan_mode_to_flag
(
int
*
mode
,
const
char
*
value
)
{
for
(
size_t
i
=
0
;
i
<
sizeof
(
ipvlan_mode
)
/
sizeof
(
ipvlan_mode
[
0
]);
i
++
)
{
if
(
strcmp
(
ipvlan_mode
[
i
].
name
,
value
)
!=
0
)
continue
;
*
mode
=
ipvlan_mode
[
i
].
mode
;
return
0
;
}
return
-
1
;
}
char
*
lxc_ipvlan_flag_to_mode
(
int
mode
)
{
for
(
size_t
i
=
0
;
i
<
sizeof
(
ipvlan_mode
)
/
sizeof
(
ipvlan_mode
[
0
]);
i
++
)
{
if
(
ipvlan_mode
[
i
].
mode
!=
mode
)
continue
;
return
ipvlan_mode
[
i
].
name
;
}
return
NULL
;
}
static
struct
lxc_ipvlan_isolation
{
char
*
name
;
int
flag
;
}
ipvlan_isolation
[]
=
{
{
"bridge"
,
IPVLAN_ISOLATION_BRIDGE
},
{
"private"
,
IPVLAN_ISOLATION_PRIVATE
},
{
"vepa"
,
IPVLAN_ISOLATION_VEPA
},
};
int
lxc_ipvlan_isolation_to_flag
(
int
*
flag
,
const
char
*
value
)
{
for
(
size_t
i
=
0
;
i
<
sizeof
(
ipvlan_isolation
)
/
sizeof
(
ipvlan_isolation
[
0
]);
i
++
)
{
if
(
strcmp
(
ipvlan_isolation
[
i
].
name
,
value
)
!=
0
)
continue
;
*
flag
=
ipvlan_isolation
[
i
].
flag
;
return
0
;
}
return
-
1
;
}
char
*
lxc_ipvlan_flag_to_isolation
(
int
flag
)
{
for
(
size_t
i
=
0
;
i
<
sizeof
(
ipvlan_isolation
)
/
sizeof
(
ipvlan_isolation
[
0
]);
i
++
)
{
if
(
ipvlan_isolation
[
i
].
flag
!=
flag
)
continue
;
return
ipvlan_isolation
[
i
].
name
;
}
return
NULL
;
}
int
set_config_string_item
(
char
**
conf_item
,
const
char
*
value
)
int
set_config_string_item
(
char
**
conf_item
,
const
char
*
value
)
{
{
char
*
new_value
;
char
*
new_value
;
...
...
src/lxc/confile_utils.h
View file @
ea84ddf9
...
@@ -58,6 +58,10 @@ extern bool lxc_remove_nic_by_idx(struct lxc_conf *conf, unsigned int idx);
...
@@ -58,6 +58,10 @@ extern bool lxc_remove_nic_by_idx(struct lxc_conf *conf, unsigned int idx);
extern
void
lxc_free_networks
(
struct
lxc_list
*
networks
);
extern
void
lxc_free_networks
(
struct
lxc_list
*
networks
);
extern
int
lxc_macvlan_mode_to_flag
(
int
*
mode
,
const
char
*
value
);
extern
int
lxc_macvlan_mode_to_flag
(
int
*
mode
,
const
char
*
value
);
extern
char
*
lxc_macvlan_flag_to_mode
(
int
mode
);
extern
char
*
lxc_macvlan_flag_to_mode
(
int
mode
);
extern
int
lxc_ipvlan_mode_to_flag
(
int
*
mode
,
const
char
*
value
);
extern
char
*
lxc_ipvlan_flag_to_mode
(
int
mode
);
extern
int
lxc_ipvlan_isolation_to_flag
(
int
*
mode
,
const
char
*
value
);
extern
char
*
lxc_ipvlan_flag_to_isolation
(
int
mode
);
extern
int
set_config_string_item
(
char
**
conf_item
,
const
char
*
value
);
extern
int
set_config_string_item
(
char
**
conf_item
,
const
char
*
value
);
extern
int
set_config_string_item_max
(
char
**
conf_item
,
const
char
*
value
,
extern
int
set_config_string_item_max
(
char
**
conf_item
,
const
char
*
value
,
...
...
src/lxc/macro.h
View file @
ea84ddf9
...
@@ -280,6 +280,14 @@ extern int __build_bug_on_failed;
...
@@ -280,6 +280,14 @@ extern int __build_bug_on_failed;
#define IFLA_MACVLAN_MODE 1
#define IFLA_MACVLAN_MODE 1
#endif
#endif
#ifndef IFLA_IPVLAN_MODE
#define IFLA_IPVLAN_MODE 1
#endif
#ifndef IFLA_IPVLAN_ISOLATION
#define IFLA_IPVLAN_ISOLATION 2
#endif
#ifndef IFLA_NEW_NETNSID
#ifndef IFLA_NEW_NETNSID
#define IFLA_NEW_NETNSID 45
#define IFLA_NEW_NETNSID 45
#endif
#endif
...
@@ -333,6 +341,30 @@ extern int __build_bug_on_failed;
...
@@ -333,6 +341,30 @@ extern int __build_bug_on_failed;
#define MACVLAN_MODE_PASSTHRU 8
#define MACVLAN_MODE_PASSTHRU 8
#endif
#endif
#ifndef IPVLAN_MODE_L2
#define IPVLAN_MODE_L2 0
#endif
#ifndef IPVLAN_MODE_L3
#define IPVLAN_MODE_L3 1
#endif
#ifndef IPVLAN_MODE_L3S
#define IPVLAN_MODE_L3S 2
#endif
#ifndef IPVLAN_ISOLATION_BRIDGE
#define IPVLAN_ISOLATION_BRIDGE 0
#endif
#ifndef IPVLAN_ISOLATION_PRIVATE
#define IPVLAN_ISOLATION_PRIVATE 1
#endif
#ifndef IPVLAN_ISOLATION_VEPA
#define IPVLAN_ISOLATION_VEPA 2
#endif
/* Attributes of RTM_NEWNSID/RTM_GETNSID messages */
/* Attributes of RTM_NEWNSID/RTM_GETNSID messages */
enum
{
enum
{
__LXC_NETNSA_NONE
,
__LXC_NETNSA_NONE
,
...
...
src/lxc/network.c
View file @
ea84ddf9
...
@@ -376,6 +376,147 @@ on_error:
...
@@ -376,6 +376,147 @@ on_error:
return
-
1
;
return
-
1
;
}
}
static
int
lxc_ipvlan_create
(
const
char
*
master
,
const
char
*
name
,
int
mode
,
int
isolation
)
{
int
err
,
index
,
len
;
struct
ifinfomsg
*
ifi
;
struct
nl_handler
nlh
;
struct
rtattr
*
nest
,
*
nest2
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
len
=
strlen
(
master
);
if
(
len
==
1
||
len
>=
IFNAMSIZ
)
return
minus_one_set_errno
(
EINVAL
);
len
=
strlen
(
name
);
if
(
len
==
1
||
len
>=
IFNAMSIZ
)
return
minus_one_set_errno
(
EINVAL
);
index
=
if_nametoindex
(
master
);
if
(
!
index
)
return
minus_one_set_errno
(
EINVAL
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
if
(
err
)
return
minus_one_set_errno
(
-
err
);
err
=
-
ENOMEM
;
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
if
(
!
nlmsg
)
goto
out
;
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
if
(
!
answer
)
goto
out
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
if
(
!
ifi
)
{
goto
out
;
}
ifi
->
ifi_family
=
AF_UNSPEC
;
err
=
-
EPROTO
;
nest
=
nla_begin_nested
(
nlmsg
,
IFLA_LINKINFO
);
if
(
!
nest
)
goto
out
;
if
(
nla_put_string
(
nlmsg
,
IFLA_INFO_KIND
,
"ipvlan"
))
goto
out
;
if
(
mode
)
{
nest2
=
nla_begin_nested
(
nlmsg
,
IFLA_INFO_DATA
);
if
(
!
nest2
)
goto
out
;
if
(
nla_put_u32
(
nlmsg
,
IFLA_IPVLAN_MODE
,
mode
))
goto
out
;
/* if_link.h does not define the isolation flag value for bridge mode so we define it as 0
* and only send mode if mode >0 as default mode is bridge anyway according to ipvlan docs.
*/
if
(
isolation
>
0
)
{
if
(
nla_put_u16
(
nlmsg
,
IFLA_IPVLAN_ISOLATION
,
isolation
))
goto
out
;
}
nla_end_nested
(
nlmsg
,
nest2
);
}
nla_end_nested
(
nlmsg
,
nest
);
if
(
nla_put_u32
(
nlmsg
,
IFLA_LINK
,
index
))
goto
out
;
if
(
nla_put_string
(
nlmsg
,
IFLA_IFNAME
,
name
))
goto
out
;
err
=
netlink_transaction
(
&
nlh
,
nlmsg
,
answer
);
out:
netlink_close
(
&
nlh
);
nlmsg_free
(
answer
);
nlmsg_free
(
nlmsg
);
if
(
err
<
0
)
return
minus_one_set_errno
(
-
err
);
return
0
;
}
static
int
instantiate_ipvlan
(
struct
lxc_handler
*
handler
,
struct
lxc_netdev
*
netdev
)
{
char
peerbuf
[
IFNAMSIZ
],
*
peer
;
int
err
;
if
(
netdev
->
link
[
0
]
==
'\0'
)
{
ERROR
(
"No link for ipvlan network device specified"
);
return
-
1
;
}
err
=
snprintf
(
peerbuf
,
sizeof
(
peerbuf
),
"ipXXXXXX"
);
if
(
err
<
0
||
(
size_t
)
err
>=
sizeof
(
peerbuf
))
return
-
1
;
peer
=
lxc_mkifname
(
peerbuf
);
if
(
!
peer
)
return
-
1
;
err
=
lxc_ipvlan_create
(
netdev
->
link
,
peer
,
netdev
->
priv
.
ipvlan_attr
.
mode
,
netdev
->
priv
.
ipvlan_attr
.
isolation
);
if
(
err
)
{
SYSERROR
(
"Failed to create ipvlan interface
\"
%s
\"
on
\"
%s
\"
"
,
peer
,
netdev
->
link
);
goto
on_error
;
}
netdev
->
ifindex
=
if_nametoindex
(
peer
);
if
(
!
netdev
->
ifindex
)
{
ERROR
(
"Failed to retrieve ifindex for
\"
%s
\"
"
,
peer
);
goto
on_error
;
}
if
(
netdev
->
upscript
)
{
char
*
argv
[]
=
{
"ipvlan"
,
netdev
->
link
,
NULL
,
};
err
=
run_script_argv
(
handler
->
name
,
handler
->
conf
->
hooks_version
,
"net"
,
netdev
->
upscript
,
"up"
,
argv
);
if
(
err
<
0
)
goto
on_error
;
}
DEBUG
(
"Instantiated ipvlan
\"
%s
\"
with ifindex is %d and mode %d"
,
peer
,
netdev
->
ifindex
,
netdev
->
priv
.
macvlan_attr
.
mode
);
return
0
;
on_error:
lxc_netdev_delete_by_name
(
peer
);
return
-
1
;
}
static
int
instantiate_vlan
(
struct
lxc_handler
*
handler
,
struct
lxc_netdev
*
netdev
)
static
int
instantiate_vlan
(
struct
lxc_handler
*
handler
,
struct
lxc_netdev
*
netdev
)
{
{
char
peer
[
IFNAMSIZ
];
char
peer
[
IFNAMSIZ
];
...
@@ -518,6 +659,7 @@ static int instantiate_none(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -518,6 +659,7 @@ static int instantiate_none(struct lxc_handler *handler, struct lxc_netdev *netd
static
instantiate_cb
netdev_conf
[
LXC_NET_MAXCONFTYPE
+
1
]
=
{
static
instantiate_cb
netdev_conf
[
LXC_NET_MAXCONFTYPE
+
1
]
=
{
[
LXC_NET_VETH
]
=
instantiate_veth
,
[
LXC_NET_VETH
]
=
instantiate_veth
,
[
LXC_NET_MACVLAN
]
=
instantiate_macvlan
,
[
LXC_NET_MACVLAN
]
=
instantiate_macvlan
,
[
LXC_NET_IPVLAN
]
=
instantiate_ipvlan
,
[
LXC_NET_VLAN
]
=
instantiate_vlan
,
[
LXC_NET_VLAN
]
=
instantiate_vlan
,
[
LXC_NET_PHYS
]
=
instantiate_phys
,
[
LXC_NET_PHYS
]
=
instantiate_phys
,
[
LXC_NET_EMPTY
]
=
instantiate_empty
,
[
LXC_NET_EMPTY
]
=
instantiate_empty
,
...
@@ -571,6 +713,26 @@ static int shutdown_macvlan(struct lxc_handler *handler, struct lxc_netdev *netd
...
@@ -571,6 +713,26 @@ static int shutdown_macvlan(struct lxc_handler *handler, struct lxc_netdev *netd
return
0
;
return
0
;
}
}
static
int
shutdown_ipvlan
(
struct
lxc_handler
*
handler
,
struct
lxc_netdev
*
netdev
)
{
int
ret
;
char
*
argv
[]
=
{
"ipvlan"
,
netdev
->
link
,
NULL
,
};
if
(
!
netdev
->
downscript
)
return
0
;
ret
=
run_script_argv
(
handler
->
name
,
handler
->
conf
->
hooks_version
,
"net"
,
netdev
->
downscript
,
"down"
,
argv
);
if
(
ret
<
0
)
return
-
1
;
return
0
;
}
static
int
shutdown_vlan
(
struct
lxc_handler
*
handler
,
struct
lxc_netdev
*
netdev
)
static
int
shutdown_vlan
(
struct
lxc_handler
*
handler
,
struct
lxc_netdev
*
netdev
)
{
{
int
ret
;
int
ret
;
...
@@ -638,6 +800,7 @@ static int shutdown_none(struct lxc_handler *handler, struct lxc_netdev *netdev)
...
@@ -638,6 +800,7 @@ static int shutdown_none(struct lxc_handler *handler, struct lxc_netdev *netdev)
static
instantiate_cb
netdev_deconf
[
LXC_NET_MAXCONFTYPE
+
1
]
=
{
static
instantiate_cb
netdev_deconf
[
LXC_NET_MAXCONFTYPE
+
1
]
=
{
[
LXC_NET_VETH
]
=
shutdown_veth
,
[
LXC_NET_VETH
]
=
shutdown_veth
,
[
LXC_NET_MACVLAN
]
=
shutdown_macvlan
,
[
LXC_NET_MACVLAN
]
=
shutdown_macvlan
,
[
LXC_NET_IPVLAN
]
=
shutdown_ipvlan
,
[
LXC_NET_VLAN
]
=
shutdown_vlan
,
[
LXC_NET_VLAN
]
=
shutdown_vlan
,
[
LXC_NET_PHYS
]
=
shutdown_phys
,
[
LXC_NET_PHYS
]
=
shutdown_phys
,
[
LXC_NET_EMPTY
]
=
shutdown_empty
,
[
LXC_NET_EMPTY
]
=
shutdown_empty
,
...
@@ -2012,6 +2175,7 @@ static const char *const lxc_network_types[LXC_NET_MAXCONFTYPE + 1] = {
...
@@ -2012,6 +2175,7 @@ static const char *const lxc_network_types[LXC_NET_MAXCONFTYPE + 1] = {
[
LXC_NET_EMPTY
]
=
"empty"
,
[
LXC_NET_EMPTY
]
=
"empty"
,
[
LXC_NET_VETH
]
=
"veth"
,
[
LXC_NET_VETH
]
=
"veth"
,
[
LXC_NET_MACVLAN
]
=
"macvlan"
,
[
LXC_NET_MACVLAN
]
=
"macvlan"
,
[
LXC_NET_IPVLAN
]
=
"ipvlan"
,
[
LXC_NET_PHYS
]
=
"phys"
,
[
LXC_NET_PHYS
]
=
"phys"
,
[
LXC_NET_VLAN
]
=
"vlan"
,
[
LXC_NET_VLAN
]
=
"vlan"
,
[
LXC_NET_NONE
]
=
"none"
,
[
LXC_NET_NONE
]
=
"none"
,
...
...
src/lxc/network.h
View file @
ea84ddf9
...
@@ -40,6 +40,7 @@ enum {
...
@@ -40,6 +40,7 @@ enum {
LXC_NET_EMPTY
,
LXC_NET_EMPTY
,
LXC_NET_VETH
,
LXC_NET_VETH
,
LXC_NET_MACVLAN
,
LXC_NET_MACVLAN
,
LXC_NET_IPVLAN
,
LXC_NET_PHYS
,
LXC_NET_PHYS
,
LXC_NET_VLAN
,
LXC_NET_VLAN
,
LXC_NET_NONE
,
LXC_NET_NONE
,
...
@@ -110,6 +111,11 @@ struct ifla_macvlan {
...
@@ -110,6 +111,11 @@ struct ifla_macvlan {
int
mode
;
/* private, vepa, bridge, passthru */
int
mode
;
/* private, vepa, bridge, passthru */
};
};
struct
ifla_ipvlan
{
int
mode
;
/* l3, l3s, l2 */
int
isolation
;
/* bridge, private, vepa */
};
/* Contains information about the physical network device as seen from the host.
/* Contains information about the physical network device as seen from the host.
* @ifindex : The ifindex of the physical network device in the host's network
* @ifindex : The ifindex of the physical network device in the host's network
* namespace.
* namespace.
...
@@ -120,6 +126,7 @@ struct ifla_phys {
...
@@ -120,6 +126,7 @@ struct ifla_phys {
union
netdev_p
{
union
netdev_p
{
struct
ifla_macvlan
macvlan_attr
;
struct
ifla_macvlan
macvlan_attr
;
struct
ifla_ipvlan
ipvlan_attr
;
struct
ifla_phys
phys_attr
;
struct
ifla_phys
phys_attr
;
struct
ifla_veth
veth_attr
;
struct
ifla_veth
veth_attr
;
struct
ifla_vlan
vlan_attr
;
struct
ifla_vlan
vlan_attr
;
...
...
src/tests/parse_config_file.c
View file @
ea84ddf9
...
@@ -666,6 +666,11 @@ int main(int argc, char *argv[])
...
@@ -666,6 +666,11 @@ int main(int argc, char *argv[])
goto
non_test_error
;
goto
non_test_error
;
}
}
if
(
set_get_compare_clear_save_load
(
c
,
"lxc.net.0.type"
,
"ipvlan"
,
tmpf
,
true
))
{
lxc_error
(
"%s
\n
"
,
"lxc.net.0.type"
);
goto
non_test_error
;
}
if
(
set_get_compare_clear_save_load
(
c
,
"lxc.net.1000.type"
,
"phys"
,
tmpf
,
true
))
{
if
(
set_get_compare_clear_save_load
(
c
,
"lxc.net.1000.type"
,
"phys"
,
tmpf
,
true
))
{
lxc_error
(
"%s
\n
"
,
"lxc.net.1000.type"
);
lxc_error
(
"%s
\n
"
,
"lxc.net.1000.type"
);
goto
non_test_error
;
goto
non_test_error
;
...
@@ -701,6 +706,36 @@ int main(int argc, char *argv[])
...
@@ -701,6 +706,36 @@ int main(int argc, char *argv[])
goto
non_test_error
;
goto
non_test_error
;
}
}
if
(
set_get_compare_clear_save_load_network
(
c
,
"lxc.net.0.ipvlan.mode"
,
"l3"
,
tmpf
,
true
,
"ipvlan"
))
{
lxc_error
(
"%s
\n
"
,
"lxc.net.0.ipvlan.mode"
);
goto
non_test_error
;
}
if
(
set_get_compare_clear_save_load_network
(
c
,
"lxc.net.0.ipvlan.mode"
,
"l3s"
,
tmpf
,
true
,
"ipvlan"
))
{
lxc_error
(
"%s
\n
"
,
"lxc.net.0.ipvlan.mode"
);
goto
non_test_error
;
}
if
(
set_get_compare_clear_save_load_network
(
c
,
"lxc.net.0.ipvlan.mode"
,
"l2"
,
tmpf
,
true
,
"ipvlan"
))
{
lxc_error
(
"%s
\n
"
,
"lxc.net.0.ipvlan.mode"
);
goto
non_test_error
;
}
if
(
set_get_compare_clear_save_load_network
(
c
,
"lxc.net.0.ipvlan.isolation"
,
"bridge"
,
tmpf
,
true
,
"ipvlan"
))
{
lxc_error
(
"%s
\n
"
,
"lxc.net.0.ipvlan.isolation"
);
goto
non_test_error
;
}
if
(
set_get_compare_clear_save_load_network
(
c
,
"lxc.net.0.ipvlan.isolation"
,
"private"
,
tmpf
,
true
,
"ipvlan"
))
{
lxc_error
(
"%s
\n
"
,
"lxc.net.0.ipvlan.isolation"
);
goto
non_test_error
;
}
if
(
set_get_compare_clear_save_load_network
(
c
,
"lxc.net.0.ipvlan.isolation"
,
"vepa"
,
tmpf
,
true
,
"ipvlan"
))
{
lxc_error
(
"%s
\n
"
,
"lxc.net.0.ipvlan.isolation"
);
goto
non_test_error
;
}
if
(
set_get_compare_clear_save_load_network
(
c
,
"lxc.net.0.veth.pair"
,
"clusterfuck"
,
tmpf
,
true
,
"veth"
))
{
if
(
set_get_compare_clear_save_load_network
(
c
,
"lxc.net.0.veth.pair"
,
"clusterfuck"
,
tmpf
,
true
,
"veth"
))
{
lxc_error
(
"%s
\n
"
,
"lxc.net.0.veth.pair"
);
lxc_error
(
"%s
\n
"
,
"lxc.net.0.veth.pair"
);
goto
non_test_error
;
goto
non_test_error
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment