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
2a25eb27
Unverified
Commit
2a25eb27
authored
Feb 26, 2021
by
Christian Brauner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
network: carry some structs to ease backports
Signed-off-by:
Christian Brauner
<
christian.brauner@ubuntu.com
>
parent
609c5019
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
362 additions
and
0 deletions
+362
-0
confile_utils.c
src/lxc/confile_utils.c
+15
-0
macro.h
src/lxc/macro.h
+28
-0
network.c
src/lxc/network.c
+316
-0
network.h
src/lxc/network.h
+3
-0
No files found.
src/lxc/confile_utils.c
View file @
2a25eb27
...
@@ -247,6 +247,7 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
...
@@ -247,6 +247,7 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
switch
(
netdev
->
type
)
{
switch
(
netdev
->
type
)
{
case
LXC_NET_VETH
:
case
LXC_NET_VETH
:
TRACE
(
"type: veth"
);
TRACE
(
"type: veth"
);
TRACE
(
"veth mode: %d"
,
netdev
->
priv
.
veth_attr
.
mode
);
if
(
netdev
->
priv
.
veth_attr
.
pair
[
0
]
!=
'\0'
)
if
(
netdev
->
priv
.
veth_attr
.
pair
[
0
]
!=
'\0'
)
TRACE
(
"veth pair: %s"
,
TRACE
(
"veth pair: %s"
,
...
@@ -259,6 +260,15 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
...
@@ -259,6 +260,15 @@ void lxc_log_configured_netdevs(const struct lxc_conf *conf)
if
(
netdev
->
priv
.
veth_attr
.
ifindex
>
0
)
if
(
netdev
->
priv
.
veth_attr
.
ifindex
>
0
)
TRACE
(
"host side ifindex for veth device: %d"
,
TRACE
(
"host side ifindex for veth device: %d"
,
netdev
->
priv
.
veth_attr
.
ifindex
);
netdev
->
priv
.
veth_attr
.
ifindex
);
if
(
netdev
->
priv
.
veth_attr
.
vlan_id_set
)
TRACE
(
"veth vlan id: %d"
,
netdev
->
priv
.
veth_attr
.
vlan_id
);
lxc_list_for_each_safe
(
cur
,
&
netdev
->
priv
.
veth_attr
.
vlan_tagged_ids
,
next
)
{
unsigned
short
vlan_tagged_id
=
PTR_TO_USHORT
(
cur
->
elem
);
TRACE
(
"veth vlan tagged id: %u"
,
vlan_tagged_id
);
}
break
;
break
;
case
LXC_NET_MACVLAN
:
case
LXC_NET_MACVLAN
:
TRACE
(
"type: macvlan"
);
TRACE
(
"type: macvlan"
);
...
@@ -432,6 +442,11 @@ static void lxc_free_netdev(struct lxc_netdev *netdev)
...
@@ -432,6 +442,11 @@ static void lxc_free_netdev(struct lxc_netdev *netdev)
free
(
cur
->
elem
);
free
(
cur
->
elem
);
free
(
cur
);
free
(
cur
);
}
}
lxc_list_for_each_safe
(
cur
,
&
netdev
->
priv
.
veth_attr
.
vlan_tagged_ids
,
next
)
{
lxc_list_del
(
cur
);
free
(
cur
);
}
}
}
free
(
netdev
);
free
(
netdev
);
...
...
src/lxc/macro.h
View file @
2a25eb27
...
@@ -548,6 +548,34 @@ extern int __build_bug_on_failed;
...
@@ -548,6 +548,34 @@ extern int __build_bug_on_failed;
#define IPVLAN_ISOLATION_VEPA 2
#define IPVLAN_ISOLATION_VEPA 2
#endif
#endif
#ifndef BRIDGE_VLAN_NONE
#define BRIDGE_VLAN_NONE -1
/* Bridge VLAN option set to "none". */
#endif
#ifndef BRIDGE_VLAN_ID_MAX
#define BRIDGE_VLAN_ID_MAX 4094
/* Bridge VLAN MAX VLAN ID. */
#endif
#ifndef BRIDGE_FLAGS_MASTER
#define BRIDGE_FLAGS_MASTER 1
/* Bridge command to/from parent */
#endif
#ifndef BRIDGE_VLAN_INFO_PVID
#define BRIDGE_VLAN_INFO_PVID (1<<1)
/* VLAN is PVID, ingress untagged */
#endif
#ifndef BRIDGE_VLAN_INFO_UNTAGGED
#define BRIDGE_VLAN_INFO_UNTAGGED (1<<2)
/* VLAN egresses untagged */
#endif
#ifndef IFLA_BRIDGE_FLAGS
#define IFLA_BRIDGE_FLAGS 0
#endif
#ifndef IFLA_BRIDGE_VLAN_INFO
#define IFLA_BRIDGE_VLAN_INFO 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 @
2a25eb27
...
@@ -307,6 +307,303 @@ static int lxc_is_ip_forwarding_enabled(const char *ifname, int family)
...
@@ -307,6 +307,303 @@ static int lxc_is_ip_forwarding_enabled(const char *ifname, int family)
return
lxc_read_file_expect
(
path
,
buf
,
1
,
"1"
);
return
lxc_read_file_expect
(
path
,
buf
,
1
,
"1"
);
}
}
struct
bridge_vlan_info
{
__u16
flags
;
__u16
vid
;
};
static
int
lxc_bridge_vlan
(
unsigned
int
ifindex
,
unsigned
short
operation
,
unsigned
short
vlan_id
,
bool
tagged
)
{
call_cleaner
(
nlmsg_free
)
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
struct
nl_handler
nlh
;
call_cleaner
(
netlink_close
)
struct
nl_handler
*
nlh_ptr
=
&
nlh
;
int
err
;
struct
ifinfomsg
*
ifi
;
struct
rtattr
*
nest
;
unsigned
short
bridge_flags
=
0
;
struct
bridge_vlan_info
vlan_info
;
err
=
netlink_open
(
nlh_ptr
,
NETLINK_ROUTE
);
if
(
err
)
return
err
;
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
if
(
!
nlmsg
)
return
ret_errno
(
ENOMEM
);
answer
=
nlmsg_alloc_reserve
(
NLMSG_GOOD_SIZE
);
if
(
!
answer
)
return
ret_errno
(
ENOMEM
);
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
operation
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
if
(
!
ifi
)
return
ret_errno
(
ENOMEM
);
ifi
->
ifi_family
=
AF_BRIDGE
;
ifi
->
ifi_index
=
ifindex
;
nest
=
nla_begin_nested
(
nlmsg
,
IFLA_AF_SPEC
);
if
(
!
nest
)
return
ret_errno
(
ENOMEM
);
bridge_flags
|=
BRIDGE_FLAGS_MASTER
;
if
(
nla_put_u16
(
nlmsg
,
IFLA_BRIDGE_FLAGS
,
bridge_flags
))
return
ret_errno
(
ENOMEM
);
vlan_info
.
vid
=
vlan_id
;
vlan_info
.
flags
=
0
;
if
(
!
tagged
)
vlan_info
.
flags
=
BRIDGE_VLAN_INFO_PVID
|
BRIDGE_VLAN_INFO_UNTAGGED
;
if
(
nla_put_buffer
(
nlmsg
,
IFLA_BRIDGE_VLAN_INFO
,
&
vlan_info
,
sizeof
(
struct
bridge_vlan_info
)))
return
ret_errno
(
ENOMEM
);
nla_end_nested
(
nlmsg
,
nest
);
return
netlink_transaction
(
nlh_ptr
,
nlmsg
,
answer
);
}
static
int
lxc_bridge_vlan_add
(
unsigned
int
ifindex
,
unsigned
short
vlan_id
,
bool
tagged
)
{
return
lxc_bridge_vlan
(
ifindex
,
RTM_SETLINK
,
vlan_id
,
tagged
);
}
static
int
lxc_bridge_vlan_del
(
unsigned
int
ifindex
,
unsigned
short
vlan_id
)
{
return
lxc_bridge_vlan
(
ifindex
,
RTM_DELLINK
,
vlan_id
,
false
);
}
static
int
lxc_bridge_vlan_add_tagged
(
unsigned
int
ifindex
,
struct
lxc_list
*
vlan_ids
)
{
struct
lxc_list
*
iterator
;
int
err
;
lxc_list_for_each
(
iterator
,
vlan_ids
)
{
unsigned
short
vlan_id
=
PTR_TO_USHORT
(
iterator
->
elem
);
err
=
lxc_bridge_vlan_add
(
ifindex
,
vlan_id
,
true
);
if
(
err
)
return
log_error_errno
(
-
1
,
-
err
,
"Failed to add tagged vlan
\"
%u
\"
to ifindex
\"
%d
\"
"
,
vlan_id
,
ifindex
);
}
return
0
;
}
static
int
validate_veth
(
struct
lxc_netdev
*
netdev
)
{
if
(
netdev
->
priv
.
veth_attr
.
mode
!=
VETH_MODE_BRIDGE
||
is_empty_string
(
netdev
->
link
))
{
/* Check that veth.vlan.id isn't being used in non bridge veth.mode. */
if
(
netdev
->
priv
.
veth_attr
.
vlan_id_set
)
return
log_error_errno
(
-
1
,
EINVAL
,
"Cannot use veth vlan.id when not in bridge mode or no bridge link specified"
);
/* Check that veth.vlan.tagged.id isn't being used in non bridge veth.mode. */
if
(
lxc_list_len
(
&
netdev
->
priv
.
veth_attr
.
vlan_tagged_ids
)
>
0
)
return
log_error_errno
(
-
1
,
EINVAL
,
"Cannot use veth vlan.id when not in bridge mode or no bridge link specified"
);
}
if
(
netdev
->
priv
.
veth_attr
.
vlan_id_set
)
{
struct
lxc_list
*
it
;
lxc_list_for_each
(
it
,
&
netdev
->
priv
.
veth_attr
.
vlan_tagged_ids
)
{
unsigned
short
i
=
PTR_TO_USHORT
(
it
->
elem
);
if
(
i
==
netdev
->
priv
.
veth_attr
.
vlan_id
)
return
log_error_errno
(
-
1
,
EINVAL
,
"Cannot use same veth vlan.id
\"
%u
\"
in vlan.tagged.id"
,
netdev
->
priv
.
veth_attr
.
vlan_id
);
}
}
return
0
;
}
static
int
setup_veth_native_bridge_vlan
(
char
*
veth1
,
struct
lxc_netdev
*
netdev
)
{
int
err
,
rc
,
veth1index
;
char
path
[
STRLITERALLEN
(
"/sys/class/net//bridge/vlan_filtering"
)
+
IFNAMSIZ
+
1
];
char
buf
[
5
];
/* Sufficient size to fit max VLAN ID (4094) and null char. */
/* Skip setup if no VLAN options are specified. */
if
(
!
netdev
->
priv
.
veth_attr
.
vlan_id_set
&&
lxc_list_len
(
&
netdev
->
priv
.
veth_attr
.
vlan_tagged_ids
)
<=
0
)
return
0
;
/* Check vlan filtering is enabled on parent bridge. */
rc
=
strnprintf
(
path
,
sizeof
(
path
),
"/sys/class/net/%s/bridge/vlan_filtering"
,
netdev
->
link
);
if
(
rc
<
0
)
return
-
1
;
rc
=
lxc_read_from_file
(
path
,
buf
,
sizeof
(
buf
));
if
(
rc
<
0
)
return
log_error_errno
(
rc
,
errno
,
"Failed reading from
\"
%s
\"
"
,
path
);
buf
[
rc
-
1
]
=
'\0'
;
if
(
!
strequal
(
buf
,
"1"
))
return
log_error_errno
(
-
1
,
EPERM
,
"vlan_filtering is not enabled on
\"
%s
\"
"
,
netdev
->
link
);
/* Get veth1 ifindex for use with netlink. */
veth1index
=
if_nametoindex
(
veth1
);
if
(
!
veth1index
)
return
log_error_errno
(
-
1
,
errno
,
"Failed getting ifindex of
\"
%s
\"
"
,
netdev
->
link
);
/* Configure untagged VLAN settings on bridge port if specified. */
if
(
netdev
->
priv
.
veth_attr
.
vlan_id_set
)
{
unsigned
short
default_pvid
;
/* Get the bridge's default VLAN PVID. */
rc
=
strnprintf
(
path
,
sizeof
(
path
),
"/sys/class/net/%s/bridge/default_pvid"
,
netdev
->
link
);
if
(
rc
<
0
)
return
-
1
;
rc
=
lxc_read_from_file
(
path
,
buf
,
sizeof
(
buf
));
if
(
rc
<
0
)
return
log_error_errno
(
rc
,
errno
,
"Failed reading from
\"
%s
\"
"
,
path
);
buf
[
rc
-
1
]
=
'\0'
;
err
=
get_u16
(
&
default_pvid
,
buf
,
0
);
if
(
err
)
return
log_error_errno
(
-
1
,
EINVAL
,
"Failed parsing default_pvid of
\"
%s
\"
"
,
netdev
->
link
);
/* If the default PVID on the port is not the specified untagged VLAN, then delete it. */
if
(
default_pvid
!=
netdev
->
priv
.
veth_attr
.
vlan_id
)
{
err
=
lxc_bridge_vlan_del
(
veth1index
,
default_pvid
);
if
(
err
)
return
log_error_errno
(
err
,
errno
,
"Failed to delete default untagged vlan
\"
%u
\"
on
\"
%s
\"
"
,
default_pvid
,
veth1
);
}
if
(
netdev
->
priv
.
veth_attr
.
vlan_id
>
BRIDGE_VLAN_NONE
)
{
err
=
lxc_bridge_vlan_add
(
veth1index
,
netdev
->
priv
.
veth_attr
.
vlan_id
,
false
);
if
(
err
)
return
log_error_errno
(
err
,
errno
,
"Failed to add untagged vlan
\"
%u
\"
on
\"
%s
\"
"
,
netdev
->
priv
.
veth_attr
.
vlan_id
,
veth1
);
}
}
/* Configure tagged VLAN settings on bridge port if specified. */
err
=
lxc_bridge_vlan_add_tagged
(
veth1index
,
&
netdev
->
priv
.
veth_attr
.
vlan_tagged_ids
);
if
(
err
)
return
log_error_errno
(
err
,
errno
,
"Failed to add tagged vlans on
\"
%s
\"
"
,
veth1
);
return
0
;
}
struct
ovs_veth_vlan_args
{
const
char
*
nic
;
const
char
*
vlan_mode
;
/* Port VLAN mode. */
short
vlan_id
;
/* PVID VLAN ID. */
char
*
trunks
;
/* Comma delimited list of tagged VLAN IDs. */
};
static
inline
void
free_ovs_veth_vlan_args
(
struct
ovs_veth_vlan_args
*
args
)
{
free_disarm
(
args
->
trunks
);
}
static
int
lxc_ovs_setup_bridge_vlan_exec
(
void
*
data
)
{
struct
ovs_veth_vlan_args
*
args
=
data
;
__do_free
char
*
vlan_mode
=
NULL
,
*
tag
=
NULL
,
*
trunks
=
NULL
;
if
(
!
args
->
vlan_mode
)
return
ret_errno
(
EINVAL
);
vlan_mode
=
must_concat
(
NULL
,
"vlan_mode="
,
args
->
vlan_mode
,
(
char
*
)
NULL
);
if
(
args
->
vlan_id
>
BRIDGE_VLAN_NONE
)
{
char
buf
[
5
];
int
rc
;
rc
=
strnprintf
(
buf
,
sizeof
(
buf
),
"%u"
,
args
->
vlan_id
);
if
(
rc
<
0
)
return
log_error_errno
(
-
1
,
EINVAL
,
"Failed to parse ovs bridge vlan
\"
%d
\"
"
,
args
->
vlan_id
);
tag
=
must_concat
(
NULL
,
"tag="
,
buf
,
(
char
*
)
NULL
);
}
if
(
args
->
trunks
)
trunks
=
must_concat
(
NULL
,
"trunks="
,
args
->
trunks
,
(
char
*
)
NULL
);
/* Detect the combination of vlan_id and trunks specified and convert to ovs-vsctl command. */
if
(
tag
&&
trunks
)
execlp
(
"ovs-vsctl"
,
"ovs-vsctl"
,
"set"
,
"port"
,
args
->
nic
,
vlan_mode
,
tag
,
trunks
,
(
char
*
)
NULL
);
else
if
(
tag
)
execlp
(
"ovs-vsctl"
,
"ovs-vsctl"
,
"set"
,
"port"
,
args
->
nic
,
vlan_mode
,
tag
,
(
char
*
)
NULL
);
else
if
(
trunks
)
execlp
(
"ovs-vsctl"
,
"ovs-vsctl"
,
"set"
,
"port"
,
args
->
nic
,
vlan_mode
,
trunks
,
(
char
*
)
NULL
);
else
return
-
EINVAL
;
return
-
errno
;
}
static
int
setup_veth_ovs_bridge_vlan
(
char
*
veth1
,
struct
lxc_netdev
*
netdev
)
{
int
taggedLength
=
lxc_list_len
(
&
netdev
->
priv
.
veth_attr
.
vlan_tagged_ids
);
struct
ovs_veth_vlan_args
args
;
args
.
nic
=
veth1
;
args
.
vlan_mode
=
NULL
;
args
.
vlan_id
=
BRIDGE_VLAN_NONE
;
args
.
trunks
=
NULL
;
/* Skip setup if no VLAN options are specified. */
if
(
!
netdev
->
priv
.
veth_attr
.
vlan_id_set
&&
taggedLength
<=
0
)
return
0
;
/* Configure untagged VLAN settings on bridge port if specified. */
if
(
netdev
->
priv
.
veth_attr
.
vlan_id_set
)
{
if
(
netdev
->
priv
.
veth_attr
.
vlan_id
==
BRIDGE_VLAN_NONE
&&
taggedLength
<=
0
)
return
log_error_errno
(
-
1
,
EINVAL
,
"Cannot use vlan.id=none with openvswitch bridges when not using vlan.tagged.id"
);
/* Configure the untagged 'native' membership settings of the port if VLAN ID specified.
* Also set the vlan_mode=access, which will drop any tagged frames.
* Order is important here, as vlan_mode is set to "access", assuming that vlan.tagged.id is not
* used. If vlan.tagged.id is specified, then we expect it to also change the vlan_mode as needed.
*/
if
(
netdev
->
priv
.
veth_attr
.
vlan_id
>
BRIDGE_VLAN_NONE
)
{
args
.
vlan_mode
=
"access"
;
args
.
vlan_id
=
netdev
->
priv
.
veth_attr
.
vlan_id
;
}
}
if
(
taggedLength
>
0
)
{
args
.
vlan_mode
=
"trunk"
;
/* Default to only allowing tagged frames (drop untagged frames). */
if
(
netdev
->
priv
.
veth_attr
.
vlan_id
>
BRIDGE_VLAN_NONE
)
{
/* If untagged vlan mode isn't "none" then allow untagged frames for port's 'native' VLAN. */
args
.
vlan_mode
=
"native-untagged"
;
}
struct
lxc_list
*
iterator
;
lxc_list_for_each
(
iterator
,
&
netdev
->
priv
.
veth_attr
.
vlan_tagged_ids
)
{
unsigned
short
vlan_id
=
PTR_TO_USHORT
(
iterator
->
elem
);
char
buf
[
5
];
/* Sufficient size to fit max VLAN ID (4094) null char. */
int
rc
;
rc
=
strnprintf
(
buf
,
sizeof
(
buf
),
"%u"
,
vlan_id
);
if
(
rc
<
0
)
{
free_ovs_veth_vlan_args
(
&
args
);
return
log_error_errno
(
-
1
,
EINVAL
,
"Failed to parse tagged vlan
\"
%u
\"
for interface
\"
%s
\"
"
,
vlan_id
,
veth1
);
}
if
(
args
.
trunks
)
args
.
trunks
=
must_concat
(
NULL
,
args
.
trunks
,
buf
,
","
,
(
char
*
)
NULL
);
else
args
.
trunks
=
must_concat
(
NULL
,
buf
,
","
,
(
char
*
)
NULL
);
}
}
if
(
args
.
vlan_mode
)
{
int
ret
;
char
cmd_output
[
PATH_MAX
];
ret
=
run_command
(
cmd_output
,
sizeof
(
cmd_output
),
lxc_ovs_setup_bridge_vlan_exec
,
(
void
*
)
&
args
);
if
(
ret
<
0
)
{
free_ovs_veth_vlan_args
(
&
args
);
return
log_error_errno
(
-
1
,
ret
,
"Failed to setup openvswitch vlan on port
\"
%s
\"
: %s"
,
args
.
nic
,
cmd_output
);
}
}
free_ovs_veth_vlan_args
(
&
args
);
return
0
;
}
static
int
netdev_configure_server_veth
(
struct
lxc_handler
*
handler
,
struct
lxc_netdev
*
netdev
)
static
int
netdev_configure_server_veth
(
struct
lxc_handler
*
handler
,
struct
lxc_netdev
*
netdev
)
{
{
int
err
;
int
err
;
...
@@ -314,6 +611,10 @@ static int netdev_configure_server_veth(struct lxc_handler *handler, struct lxc_
...
@@ -314,6 +611,10 @@ static int netdev_configure_server_veth(struct lxc_handler *handler, struct lxc_
char
*
veth1
,
*
veth2
;
char
*
veth1
,
*
veth2
;
char
veth1buf
[
IFNAMSIZ
],
veth2buf
[
IFNAMSIZ
];
char
veth1buf
[
IFNAMSIZ
],
veth2buf
[
IFNAMSIZ
];
err
=
validate_veth
(
netdev
);
if
(
err
)
return
err
;
if
(
!
is_empty_string
(
netdev
->
priv
.
veth_attr
.
pair
))
{
if
(
!
is_empty_string
(
netdev
->
priv
.
veth_attr
.
pair
))
{
veth1
=
netdev
->
priv
.
veth_attr
.
pair
;
veth1
=
netdev
->
priv
.
veth_attr
.
pair
;
if
(
handler
->
conf
->
reboot
)
if
(
handler
->
conf
->
reboot
)
...
@@ -415,6 +716,21 @@ static int netdev_configure_server_veth(struct lxc_handler *handler, struct lxc_
...
@@ -415,6 +716,21 @@ static int netdev_configure_server_veth(struct lxc_handler *handler, struct lxc_
goto
out_delete
;
goto
out_delete
;
}
}
INFO
(
"Attached
\"
%s
\"
to bridge
\"
%s
\"
"
,
veth1
,
netdev
->
link
);
INFO
(
"Attached
\"
%s
\"
to bridge
\"
%s
\"
"
,
veth1
,
netdev
->
link
);
if
(
is_ovs_bridge
(
netdev
->
link
))
{
err
=
setup_veth_ovs_bridge_vlan
(
veth1
,
netdev
);
if
(
err
)
{
SYSERROR
(
"Failed to setup openvswitch bridge vlan on
\"
%s
\"
"
,
veth1
);
lxc_ovs_delete_port
(
netdev
->
link
,
veth1
);
goto
out_delete
;
}
}
else
{
err
=
setup_veth_native_bridge_vlan
(
veth1
,
netdev
);
if
(
err
)
{
SYSERROR
(
"Failed to setup native bridge vlan on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
}
}
}
err
=
lxc_netdev_up
(
veth1
);
err
=
lxc_netdev_up
(
veth1
);
...
...
src/lxc/network.h
View file @
2a25eb27
...
@@ -80,6 +80,9 @@ struct ifla_veth {
...
@@ -80,6 +80,9 @@ struct ifla_veth {
struct
lxc_list
ipv4_routes
;
struct
lxc_list
ipv4_routes
;
struct
lxc_list
ipv6_routes
;
struct
lxc_list
ipv6_routes
;
int
mode
;
/* bridge, router */
int
mode
;
/* bridge, router */
short
vlan_id
;
bool
vlan_id_set
;
struct
lxc_list
vlan_tagged_ids
;
};
};
struct
ifla_vlan
{
struct
ifla_vlan
{
...
...
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