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
ebc73a67
Unverified
Commit
ebc73a67
authored
Aug 24, 2017
by
Christian Brauner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
network: non-functional changes
Signed-off-by:
Christian Brauner
<
christian.brauner@ubuntu.com
>
parent
cb0dc11b
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
278 additions
and
276 deletions
+278
-276
network.c
src/lxc/network.c
+246
-214
network.h
src/lxc/network.h
+32
-62
No files found.
src/lxc/network.c
View file @
ebc73a67
...
@@ -92,12 +92,12 @@
...
@@ -92,12 +92,12 @@
lxc_log_define
(
lxc_network
,
lxc
);
lxc_log_define
(
lxc_network
,
lxc
);
int
lxc_netdev_move_by_index
(
int
ifindex
,
pid_t
pid
,
const
char
*
ifname
)
int
lxc_netdev_move_by_index
(
int
ifindex
,
pid_t
pid
,
const
char
*
ifname
)
{
{
int
err
;
struct
nl_handler
nlh
;
struct
nl_handler
nlh
;
struct
nlmsg
*
nlmsg
=
NULL
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
int
err
;
struct
nlmsg
*
nlmsg
=
NULL
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
...
@@ -108,7 +108,7 @@ int lxc_netdev_move_by_index(int ifindex, pid_t pid, const char* ifname)
...
@@ -108,7 +108,7 @@ int lxc_netdev_move_by_index(int ifindex, pid_t pid, const char* ifname)
if
(
!
nlmsg
)
if
(
!
nlmsg
)
goto
out
;
goto
out
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
...
@@ -132,42 +132,47 @@ out:
...
@@ -132,42 +132,47 @@ out:
return
err
;
return
err
;
}
}
/*
/* If we are asked to move a wireless interface, then we must actually move its
* If we are asked to move a wireless interface, then
* phyN device. Detect that condition and return the physname here. The physname
* we must actually move its phyN device. Detect
* will be passed to lxc_netdev_move_wlan() which will free it when done.
* that condition and return the physname here. The
* physname will be passed to lxc_netdev_move_wlan()
* which will free it when done
*/
*/
#define PHYSNAME "/sys/class/net/%s/phy80211/name"
#define PHYSNAME "/sys/class/net/%s/phy80211/name"
static
char
*
is_wlan
(
const
char
*
ifname
)
static
char
*
is_wlan
(
const
char
*
ifname
)
{
{
char
*
path
,
*
physname
=
NULL
;
int
i
,
ret
;
size_t
len
=
strlen
(
ifname
)
+
strlen
(
PHYSNAME
)
-
1
;
struct
stat
sb
;
long
physlen
;
long
physlen
;
size_t
len
;
char
*
path
;
FILE
*
f
;
FILE
*
f
;
int
ret
,
i
;
struct
stat
sb
;
char
*
physname
=
NULL
;
path
=
alloca
(
len
+
1
);
len
=
strlen
(
ifname
)
+
strlen
(
PHYSNAME
)
-
1
;
path
=
alloca
(
len
+
1
);
ret
=
snprintf
(
path
,
len
,
PHYSNAME
,
ifname
);
ret
=
snprintf
(
path
,
len
,
PHYSNAME
,
ifname
);
if
(
ret
<
0
||
ret
>=
len
)
if
(
ret
<
0
||
(
size_t
)
ret
>=
len
)
goto
bad
;
goto
bad
;
ret
=
stat
(
path
,
&
sb
);
ret
=
stat
(
path
,
&
sb
);
if
(
ret
)
if
(
ret
)
goto
bad
;
goto
bad
;
if
(
!
(
f
=
fopen
(
path
,
"r"
)))
f
=
fopen
(
path
,
"r"
);
if
(
!
f
)
goto
bad
;
goto
bad
;
/* Feh - sb.st_size is always 4096. */
/* Feh - sb.st_size is always 4096. */
fseek
(
f
,
0
,
SEEK_END
);
fseek
(
f
,
0
,
SEEK_END
);
physlen
=
ftell
(
f
);
physlen
=
ftell
(
f
);
fseek
(
f
,
0
,
SEEK_SET
);
fseek
(
f
,
0
,
SEEK_SET
);
physname
=
malloc
(
physlen
+
1
);
physname
=
malloc
(
physlen
+
1
);
if
(
!
physname
)
{
if
(
!
physname
)
{
fclose
(
f
);
fclose
(
f
);
goto
bad
;
goto
bad
;
}
}
memset
(
physname
,
0
,
physlen
+
1
);
memset
(
physname
,
0
,
physlen
+
1
);
ret
=
fread
(
physname
,
1
,
physlen
,
f
);
ret
=
fread
(
physname
,
1
,
physlen
,
f
);
fclose
(
f
);
fclose
(
f
);
if
(
ret
<
0
)
if
(
ret
<
0
)
...
@@ -176,6 +181,7 @@ static char * is_wlan(const char *ifname)
...
@@ -176,6 +181,7 @@ static char * is_wlan(const char *ifname)
for
(
i
=
0
;
i
<
physlen
;
i
++
)
{
for
(
i
=
0
;
i
<
physlen
;
i
++
)
{
if
(
physname
[
i
]
==
'\n'
)
if
(
physname
[
i
]
==
'\n'
)
physname
[
i
]
=
'\0'
;
physname
[
i
]
=
'\0'
;
if
(
physname
[
i
]
==
'\0'
)
if
(
physname
[
i
]
==
'\0'
)
break
;
break
;
}
}
...
@@ -187,30 +193,34 @@ bad:
...
@@ -187,30 +193,34 @@ bad:
return
NULL
;
return
NULL
;
}
}
static
int
static
int
lxc_netdev_rename_by_name_in_netns
(
pid_t
pid
,
const
char
*
old
,
lxc_netdev_rename_by_name_in_netns
(
pid_t
pid
,
const
char
*
old
,
const
char
*
new
)
const
char
*
new
)
{
{
pid_t
fpid
=
fork
()
;
pid_t
fpid
;
fpid
=
fork
();
if
(
fpid
<
0
)
if
(
fpid
<
0
)
return
-
1
;
return
-
1
;
if
(
fpid
!=
0
)
if
(
fpid
!=
0
)
return
wait_for_pid
(
fpid
);
return
wait_for_pid
(
fpid
);
if
(
!
switch_to_ns
(
pid
,
"net"
))
if
(
!
switch_to_ns
(
pid
,
"net"
))
return
-
1
;
return
-
1
;
exit
(
lxc_netdev_rename_by_name
(
old
,
new
));
exit
(
lxc_netdev_rename_by_name
(
old
,
new
));
}
}
static
int
static
int
lxc_netdev_move_wlan
(
char
*
physname
,
const
char
*
ifname
,
pid_t
pid
,
lxc_netdev_move_wlan
(
char
*
physname
,
const
char
*
ifname
,
pid_t
pid
,
const
char
*
newname
)
const
char
*
newname
)
{
{
int
err
=
-
1
;
pid_t
fpid
;
char
*
cmd
;
char
*
cmd
;
pid_t
fpid
;
int
err
=
-
1
;
/* Move phyN into the container. TODO - do this using netlink.
/* Move phyN into the container. TODO - do this using netlink.
* However, IIUC this involves a bit more complicated work to
* However, IIUC this involves a bit more complicated work to
talk to
* t
alk to the 80211 module, so for now just call out to iw
* t
he 80211 module, so for now just call out to iw.
*/
*/
cmd
=
on_path
(
"iw"
,
NULL
);
cmd
=
on_path
(
"iw"
,
NULL
);
if
(
!
cmd
)
if
(
!
cmd
)
...
@@ -220,13 +230,15 @@ lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid, const char*
...
@@ -220,13 +230,15 @@ lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid, const char*
fpid
=
fork
();
fpid
=
fork
();
if
(
fpid
<
0
)
if
(
fpid
<
0
)
goto
out1
;
goto
out1
;
if
(
fpid
==
0
)
{
if
(
fpid
==
0
)
{
char
pidstr
[
30
];
char
pidstr
[
30
];
sprintf
(
pidstr
,
"%d"
,
pid
);
sprintf
(
pidstr
,
"%d"
,
pid
);
if
(
execlp
(
"iw"
,
"iw"
,
"phy"
,
physname
,
"set"
,
"netns"
,
pidstr
,
(
char
*
)
NULL
))
execlp
(
"iw"
,
"iw"
,
"phy"
,
physname
,
"set"
,
"netns"
,
pidstr
,
exit
(
1
);
(
char
*
)
NULL
);
exit
(
0
);
/* notreached */
exit
(
EXIT_FAILURE
);
}
}
if
(
wait_for_pid
(
fpid
))
if
(
wait_for_pid
(
fpid
))
goto
out1
;
goto
out1
;
...
@@ -251,7 +263,8 @@ int lxc_netdev_move_by_name(const char *ifname, pid_t pid, const char* newname)
...
@@ -251,7 +263,8 @@ int lxc_netdev_move_by_name(const char *ifname, pid_t pid, const char* newname)
if
(
!
index
)
if
(
!
index
)
return
-
EINVAL
;
return
-
EINVAL
;
if
((
physname
=
is_wlan
(
ifname
)))
physname
=
is_wlan
(
ifname
);
if
(
physname
)
return
lxc_netdev_move_wlan
(
physname
,
ifname
,
pid
,
newname
);
return
lxc_netdev_move_wlan
(
physname
,
ifname
,
pid
,
newname
);
return
lxc_netdev_move_by_index
(
index
,
pid
,
newname
);
return
lxc_netdev_move_by_index
(
index
,
pid
,
newname
);
...
@@ -259,10 +272,10 @@ int lxc_netdev_move_by_name(const char *ifname, pid_t pid, const char* newname)
...
@@ -259,10 +272,10 @@ int lxc_netdev_move_by_name(const char *ifname, pid_t pid, const char* newname)
int
lxc_netdev_delete_by_index
(
int
ifindex
)
int
lxc_netdev_delete_by_index
(
int
ifindex
)
{
{
struct
nl_handler
nlh
;
struct
nlmsg
*
nlmsg
=
NULL
,
*
answer
=
NULL
;
struct
ifinfomsg
*
ifi
;
int
err
;
int
err
;
struct
ifinfomsg
*
ifi
;
struct
nl_handler
nlh
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
...
@@ -277,7 +290,7 @@ int lxc_netdev_delete_by_index(int ifindex)
...
@@ -277,7 +290,7 @@ int lxc_netdev_delete_by_index(int ifindex)
if
(
!
answer
)
if
(
!
answer
)
goto
out
;
goto
out
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_ACK
|
NLM_F_REQUEST
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_ACK
|
NLM_F_REQUEST
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_DELLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_DELLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
...
@@ -307,10 +320,10 @@ int lxc_netdev_delete_by_name(const char *name)
...
@@ -307,10 +320,10 @@ int lxc_netdev_delete_by_name(const char *name)
int
lxc_netdev_rename_by_index
(
int
ifindex
,
const
char
*
newname
)
int
lxc_netdev_rename_by_index
(
int
ifindex
,
const
char
*
newname
)
{
{
struct
nl_handler
nlh
;
int
err
,
len
;
struct
nlmsg
*
nlmsg
=
NULL
,
*
answer
=
NULL
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
int
len
,
err
;
struct
nl_handler
nlh
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
...
@@ -329,7 +342,7 @@ int lxc_netdev_rename_by_index(int ifindex, const char *newname)
...
@@ -329,7 +342,7 @@ int lxc_netdev_rename_by_index(int ifindex, const char *newname)
if
(
!
answer
)
if
(
!
answer
)
goto
out
;
goto
out
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_ACK
|
NLM_F_REQUEST
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_ACK
|
NLM_F_REQUEST
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
...
@@ -366,10 +379,10 @@ int lxc_netdev_rename_by_name(const char *oldname, const char *newname)
...
@@ -366,10 +379,10 @@ int lxc_netdev_rename_by_name(const char *oldname, const char *newname)
int
netdev_set_flag
(
const
char
*
name
,
int
flag
)
int
netdev_set_flag
(
const
char
*
name
,
int
flag
)
{
{
struct
nl_handler
nlh
;
int
err
,
index
,
len
;
struct
nlmsg
*
nlmsg
=
NULL
,
*
answer
=
NULL
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
int
index
,
len
,
err
;
struct
nl_handler
nlh
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
...
@@ -394,7 +407,7 @@ int netdev_set_flag(const char *name, int flag)
...
@@ -394,7 +407,7 @@ int netdev_set_flag(const char *name, int flag)
if
(
!
index
)
if
(
!
index
)
goto
out
;
goto
out
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
...
@@ -415,12 +428,12 @@ out:
...
@@ -415,12 +428,12 @@ out:
return
err
;
return
err
;
}
}
int
netdev_get_flag
(
const
char
*
name
,
int
*
flag
)
int
netdev_get_flag
(
const
char
*
name
,
int
*
flag
)
{
{
struct
nl_handler
nlh
;
int
err
,
index
,
len
;
struct
nlmsg
*
nlmsg
=
NULL
,
*
answer
=
NULL
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
int
index
,
len
,
err
;
struct
nl_handler
nlh
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
if
(
!
name
)
if
(
!
name
)
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -483,30 +496,28 @@ out:
...
@@ -483,30 +496,28 @@ out:
* 1 means interface is up.
* 1 means interface is up.
* Others means error happened, and ret-value is the error number.
* Others means error happened, and ret-value is the error number.
*/
*/
int
lxc_netdev_isup
(
const
char
*
name
)
int
lxc_netdev_isup
(
const
char
*
name
)
{
{
int
flag
;
int
err
,
flag
;
int
err
;
err
=
netdev_get_flag
(
name
,
&
flag
);
err
=
netdev_get_flag
(
name
,
&
flag
);
if
(
err
)
if
(
err
)
goto
out
;
return
err
;
if
(
flag
&
IFF_UP
)
if
(
flag
&
IFF_UP
)
return
1
;
return
1
;
return
0
;
return
0
;
out:
return
err
;
}
}
int
netdev_get_mtu
(
int
ifindex
)
int
netdev_get_mtu
(
int
ifindex
)
{
{
int
answer_len
,
err
,
res
;
struct
nl_handler
nlh
;
struct
nl_handler
nlh
;
struct
nlmsg
*
nlmsg
=
NULL
,
*
answer
=
NULL
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
struct
nlmsghdr
*
msg
;
struct
nlmsghdr
*
msg
;
int
err
,
res
;
int
readmore
=
0
,
recv_len
=
0
;
int
recv_len
=
0
,
answer_len
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
int
readmore
=
0
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
...
@@ -523,10 +534,11 @@ int netdev_get_mtu(int ifindex)
...
@@ -523,10 +534,11 @@ int netdev_get_mtu(int ifindex)
/* Save the answer buffer length, since it will be overwritten
/* Save the answer buffer length, since it will be overwritten
* on the first receive (and we might need to receive more than
* on the first receive (and we might need to receive more than
* once. */
* once.
*/
answer_len
=
answer
->
nlmsghdr
->
nlmsg_len
;
answer_len
=
answer
->
nlmsghdr
->
nlmsg_len
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_DUMP
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_DUMP
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_GETLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_GETLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
...
@@ -542,7 +554,8 @@ int netdev_get_mtu(int ifindex)
...
@@ -542,7 +554,8 @@ int netdev_get_mtu(int ifindex)
do
{
do
{
/* Restore the answer buffer length, it might have been
/* Restore the answer buffer length, it might have been
* overwritten by a previous receive. */
* overwritten by a previous receive.
*/
answer
->
nlmsghdr
->
nlmsg_len
=
answer_len
;
answer
->
nlmsghdr
->
nlmsg_len
=
answer_len
;
/* Get the (next) batch of reply messages */
/* Get the (next) batch of reply messages */
...
@@ -560,7 +573,8 @@ int netdev_get_mtu(int ifindex)
...
@@ -560,7 +573,8 @@ int netdev_get_mtu(int ifindex)
/* Stop reading if we see an error message */
/* Stop reading if we see an error message */
if
(
msg
->
nlmsg_type
==
NLMSG_ERROR
)
{
if
(
msg
->
nlmsg_type
==
NLMSG_ERROR
)
{
struct
nlmsgerr
*
errmsg
=
(
struct
nlmsgerr
*
)
NLMSG_DATA
(
msg
);
struct
nlmsgerr
*
errmsg
=
(
struct
nlmsgerr
*
)
NLMSG_DATA
(
msg
);
err
=
errmsg
->
error
;
err
=
errmsg
->
error
;
goto
out
;
goto
out
;
}
}
...
@@ -574,32 +588,34 @@ int netdev_get_mtu(int ifindex)
...
@@ -574,32 +588,34 @@ int netdev_get_mtu(int ifindex)
ifi
=
NLMSG_DATA
(
msg
);
ifi
=
NLMSG_DATA
(
msg
);
if
(
ifi
->
ifi_index
==
ifindex
)
{
if
(
ifi
->
ifi_index
==
ifindex
)
{
struct
rtattr
*
rta
=
IFLA_RTA
(
ifi
);
struct
rtattr
*
rta
=
IFLA_RTA
(
ifi
);
int
attr_len
=
msg
->
nlmsg_len
-
NLMSG_LENGTH
(
sizeof
(
*
ifi
));
int
attr_len
=
msg
->
nlmsg_len
-
NLMSG_LENGTH
(
sizeof
(
*
ifi
));
res
=
0
;
res
=
0
;
while
(
RTA_OK
(
rta
,
attr_len
))
{
while
(
RTA_OK
(
rta
,
attr_len
))
{
/* Found a local address for the requested interface,
/* Found a local address for the
* return it. */
* requested interface, return it.
*/
if
(
rta
->
rta_type
==
IFLA_MTU
)
{
if
(
rta
->
rta_type
==
IFLA_MTU
)
{
memcpy
(
&
res
,
RTA_DATA
(
rta
),
sizeof
(
int
));
memcpy
(
&
res
,
RTA_DATA
(
rta
),
sizeof
(
int
));
err
=
res
;
err
=
res
;
goto
out
;
goto
out
;
}
}
rta
=
RTA_NEXT
(
rta
,
attr_len
);
rta
=
RTA_NEXT
(
rta
,
attr_len
);
}
}
}
}
/* Keep reading more data from the socket if the
/* Keep reading more data from the socket if the last
* last message had the NLF_F_MULTI flag set */
* message had the NLF_F_MULTI flag set.
*/
readmore
=
(
msg
->
nlmsg_flags
&
NLM_F_MULTI
);
readmore
=
(
msg
->
nlmsg_flags
&
NLM_F_MULTI
);
/* Look at the next message received in this buffer */
/* Look at the next message received in this buffer
.
*/
msg
=
NLMSG_NEXT
(
msg
,
recv_len
);
msg
=
NLMSG_NEXT
(
msg
,
recv_len
);
}
}
}
while
(
readmore
);
}
while
(
readmore
);
/* If we end up here, we didn't find any result, so signal an
/* If we end up here, we didn't find any result, so signal an error. */
* error */
err
=
-
1
;
err
=
-
1
;
out:
out:
...
@@ -611,10 +627,10 @@ out:
...
@@ -611,10 +627,10 @@ out:
int
lxc_netdev_set_mtu
(
const
char
*
name
,
int
mtu
)
int
lxc_netdev_set_mtu
(
const
char
*
name
,
int
mtu
)
{
{
struct
nl_handler
nlh
;
int
err
,
index
,
len
;
struct
nlmsg
*
nlmsg
=
NULL
,
*
answer
=
NULL
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
int
index
,
len
,
err
;
struct
nl_handler
nlh
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
...
@@ -639,7 +655,7 @@ int lxc_netdev_set_mtu(const char *name, int mtu)
...
@@ -639,7 +655,7 @@ int lxc_netdev_set_mtu(const char *name, int mtu)
if
(
!
index
)
if
(
!
index
)
goto
out
;
goto
out
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
...
@@ -673,11 +689,11 @@ int lxc_netdev_down(const char *name)
...
@@ -673,11 +689,11 @@ int lxc_netdev_down(const char *name)
int
lxc_veth_create
(
const
char
*
name1
,
const
char
*
name2
)
int
lxc_veth_create
(
const
char
*
name1
,
const
char
*
name2
)
{
{
struct
nl_handler
nlh
;
int
err
,
len
;
struct
nlmsg
*
nlmsg
=
NULL
,
*
answer
=
NULL
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
struct
nl_handler
nlh
;
struct
rtattr
*
nest1
,
*
nest2
,
*
nest3
;
struct
rtattr
*
nest1
,
*
nest2
,
*
nest3
;
int
len
,
err
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
...
@@ -702,7 +718,7 @@ int lxc_veth_create(const char *name1, const char *name2)
...
@@ -702,7 +718,7 @@ int lxc_veth_create(const char *name1, const char *name2)
goto
out
;
goto
out
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
|
NLM_F_ACK
;
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
...
@@ -736,9 +752,7 @@ int lxc_veth_create(const char *name1, const char *name2)
...
@@ -736,9 +752,7 @@ int lxc_veth_create(const char *name1, const char *name2)
goto
out
;
goto
out
;
nla_end_nested
(
nlmsg
,
nest3
);
nla_end_nested
(
nlmsg
,
nest3
);
nla_end_nested
(
nlmsg
,
nest2
);
nla_end_nested
(
nlmsg
,
nest2
);
nla_end_nested
(
nlmsg
,
nest1
);
nla_end_nested
(
nlmsg
,
nest1
);
if
(
nla_put_string
(
nlmsg
,
IFLA_IFNAME
,
name1
))
if
(
nla_put_string
(
nlmsg
,
IFLA_IFNAME
,
name1
))
...
@@ -752,14 +766,14 @@ out:
...
@@ -752,14 +766,14 @@ out:
return
err
;
return
err
;
}
}
/*
XXX
: merge with lxc_macvlan_create */
/*
TODO
: merge with lxc_macvlan_create */
int
lxc_vlan_create
(
const
char
*
master
,
const
char
*
name
,
unsigned
short
vlanid
)
int
lxc_vlan_create
(
const
char
*
master
,
const
char
*
name
,
unsigned
short
vlanid
)
{
{
struct
nl_handler
nlh
;
int
err
,
len
,
lindex
;
struct
nlmsg
*
nlmsg
=
NULL
,
*
answer
=
NULL
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
struct
nl_handler
nlh
;
struct
rtattr
*
nest
,
*
nest2
;
struct
rtattr
*
nest
,
*
nest2
;
int
lindex
,
len
,
err
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
...
@@ -789,7 +803,7 @@ int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid)
...
@@ -789,7 +803,7 @@ int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid)
goto
err1
;
goto
err1
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
|
NLM_F_ACK
;
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
...
@@ -814,7 +828,6 @@ int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid)
...
@@ -814,7 +828,6 @@ int lxc_vlan_create(const char *master, const char *name, unsigned short vlanid)
goto
err1
;
goto
err1
;
nla_end_nested
(
nlmsg
,
nest2
);
nla_end_nested
(
nlmsg
,
nest2
);
nla_end_nested
(
nlmsg
,
nest
);
nla_end_nested
(
nlmsg
,
nest
);
if
(
nla_put_u32
(
nlmsg
,
IFLA_LINK
,
lindex
))
if
(
nla_put_u32
(
nlmsg
,
IFLA_LINK
,
lindex
))
...
@@ -835,11 +848,11 @@ err3:
...
@@ -835,11 +848,11 @@ err3:
int
lxc_macvlan_create
(
const
char
*
master
,
const
char
*
name
,
int
mode
)
int
lxc_macvlan_create
(
const
char
*
master
,
const
char
*
name
,
int
mode
)
{
{
struct
nl_handler
nlh
;
int
err
,
index
,
len
;
struct
nlmsg
*
nlmsg
=
NULL
,
*
answer
=
NULL
;
struct
ifinfomsg
*
ifi
;
struct
ifinfomsg
*
ifi
;
struct
nl_handler
nlh
;
struct
rtattr
*
nest
,
*
nest2
;
struct
rtattr
*
nest
,
*
nest2
;
int
index
,
len
,
err
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
...
@@ -869,7 +882,7 @@ int lxc_macvlan_create(const char *master, const char *name, int mode)
...
@@ -869,7 +882,7 @@ int lxc_macvlan_create(const char *master, const char *name, int mode)
goto
out
;
goto
out
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
|
NLM_F_ACK
;
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
|
NLM_F_ACK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWLINK
;
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
ifi
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifinfomsg
));
...
@@ -915,7 +928,8 @@ out:
...
@@ -915,7 +928,8 @@ out:
static
int
proc_sys_net_write
(
const
char
*
path
,
const
char
*
value
)
static
int
proc_sys_net_write
(
const
char
*
path
,
const
char
*
value
)
{
{
int
fd
,
err
=
0
;
int
fd
;
int
err
=
0
;
fd
=
open
(
path
,
O_WRONLY
);
fd
=
open
(
path
,
O_WRONLY
);
if
(
fd
<
0
)
if
(
fd
<
0
)
...
@@ -930,18 +944,18 @@ static int proc_sys_net_write(const char *path, const char *value)
...
@@ -930,18 +944,18 @@ static int proc_sys_net_write(const char *path, const char *value)
static
int
ip_forward_set
(
const
char
*
ifname
,
int
family
,
int
flag
)
static
int
ip_forward_set
(
const
char
*
ifname
,
int
family
,
int
flag
)
{
{
char
path
[
MAXPATHLEN
];
int
rc
;
int
rc
;
char
path
[
MAXPATHLEN
];
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
return
-
EINVAL
;
return
-
EINVAL
;
rc
=
snprintf
(
path
,
MAXPATHLEN
,
"/proc/sys/net/%s/conf/%s/forwarding"
,
rc
=
snprintf
(
path
,
MAXPATHLEN
,
"/proc/sys/net/%s/conf/%s/forwarding"
,
family
==
AF_INET
?
"ipv4"
:
"ipv6"
,
ifname
);
family
==
AF_INET
?
"ipv4"
:
"ipv6"
,
ifname
);
if
(
rc
>=
MAXPATHLEN
)
if
(
rc
<
0
||
(
size_t
)
rc
>=
MAXPATHLEN
)
return
-
E2BIG
;
return
-
E2BIG
;
return
proc_sys_net_write
(
path
,
flag
?
"1"
:
"0"
);
return
proc_sys_net_write
(
path
,
flag
?
"1"
:
"0"
);
}
}
int
lxc_ip_forward_on
(
const
char
*
ifname
,
int
family
)
int
lxc_ip_forward_on
(
const
char
*
ifname
,
int
family
)
...
@@ -956,19 +970,19 @@ int lxc_ip_forward_off(const char *ifname, int family)
...
@@ -956,19 +970,19 @@ int lxc_ip_forward_off(const char *ifname, int family)
static
int
neigh_proxy_set
(
const
char
*
ifname
,
int
family
,
int
flag
)
static
int
neigh_proxy_set
(
const
char
*
ifname
,
int
family
,
int
flag
)
{
{
char
path
[
MAXPATHLEN
];
int
ret
;
int
ret
;
char
path
[
MAXPATHLEN
];
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
return
-
EINVAL
;
return
-
EINVAL
;
ret
=
snprintf
(
path
,
MAXPATHLEN
,
"/proc/sys/net/%s/conf/%s/%s"
,
ret
=
snprintf
(
path
,
MAXPATHLEN
,
"/proc/sys/net/%s/conf/%s/%s"
,
family
==
AF_INET
?
"ipv4"
:
"ipv6"
,
ifname
,
family
==
AF_INET
?
"ipv4"
:
"ipv6"
,
ifname
,
family
==
AF_INET
?
"proxy_arp"
:
"proxy_ndp"
);
family
==
AF_INET
?
"proxy_arp"
:
"proxy_ndp"
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
if
(
ret
<
0
||
(
size_t
)
ret
>=
MAXPATHLEN
)
return
-
E2BIG
;
return
-
E2BIG
;
return
proc_sys_net_write
(
path
,
flag
?
"1"
:
"0"
);
return
proc_sys_net_write
(
path
,
flag
?
"1"
:
"0"
);
}
}
int
lxc_neigh_proxy_on
(
const
char
*
name
,
int
family
)
int
lxc_neigh_proxy_on
(
const
char
*
name
,
int
family
)
...
@@ -983,10 +997,10 @@ int lxc_neigh_proxy_off(const char *name, int family)
...
@@ -983,10 +997,10 @@ int lxc_neigh_proxy_off(const char *name, int family)
int
lxc_convert_mac
(
char
*
macaddr
,
struct
sockaddr
*
sockaddr
)
int
lxc_convert_mac
(
char
*
macaddr
,
struct
sockaddr
*
sockaddr
)
{
{
unsigned
char
*
data
;
char
c
;
int
i
=
0
;
int
i
=
0
;
unsigned
val
;
unsigned
val
;
char
c
;
unsigned
char
*
data
;
sockaddr
->
sa_family
=
ARPHRD_ETHER
;
sockaddr
->
sa_family
=
ARPHRD_ETHER
;
data
=
(
unsigned
char
*
)
sockaddr
->
sa_data
;
data
=
(
unsigned
char
*
)
sockaddr
->
sa_data
;
...
@@ -1000,9 +1014,9 @@ int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr)
...
@@ -1000,9 +1014,9 @@ int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr)
val
=
c
-
'a'
+
10
;
val
=
c
-
'a'
+
10
;
else
if
(
c
>=
'A'
&&
c
<=
'F'
)
else
if
(
c
>=
'A'
&&
c
<=
'F'
)
val
=
c
-
'A'
+
10
;
val
=
c
-
'A'
+
10
;
else
{
else
return
-
EINVAL
;
return
-
EINVAL
;
}
val
<<=
4
;
val
<<=
4
;
c
=
*
macaddr
;
c
=
*
macaddr
;
if
(
isdigit
(
c
))
if
(
isdigit
(
c
))
...
@@ -1013,12 +1027,11 @@ int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr)
...
@@ -1013,12 +1027,11 @@ int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr)
val
|=
c
-
'A'
+
10
;
val
|=
c
-
'A'
+
10
;
else
if
(
c
==
':'
||
c
==
0
)
else
if
(
c
==
':'
||
c
==
0
)
val
>>=
4
;
val
>>=
4
;
else
{
else
return
-
EINVAL
;
return
-
EINVAL
;
}
if
(
c
!=
0
)
if
(
c
!=
0
)
macaddr
++
;
macaddr
++
;
*
data
++
=
(
unsigned
char
)
(
val
&
0377
);
*
data
++
=
(
unsigned
char
)
(
val
&
0377
);
i
++
;
i
++
;
if
(
*
macaddr
==
':'
)
if
(
*
macaddr
==
':'
)
...
@@ -1028,17 +1041,16 @@ int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr)
...
@@ -1028,17 +1041,16 @@ int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr)
return
0
;
return
0
;
}
}
static
int
ip_addr_add
(
int
family
,
int
ifindex
,
static
int
ip_addr_add
(
int
family
,
int
ifindex
,
void
*
addr
,
void
*
bcast
,
void
*
a
ddr
,
void
*
bcast
,
void
*
a
cast
,
int
prefix
)
void
*
acast
,
int
prefix
)
{
{
struct
nl_handler
nlh
;
int
addrlen
,
err
;
struct
nlmsg
*
nlmsg
=
NULL
,
*
answer
=
NULL
;
struct
ifaddrmsg
*
ifa
;
struct
ifaddrmsg
*
ifa
;
int
addrlen
;
struct
nl_handler
nlh
;
int
err
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
addrlen
=
family
==
AF_INET
?
sizeof
(
struct
in_addr
)
:
addrlen
=
family
==
AF_INET
?
sizeof
(
struct
in_addr
)
sizeof
(
struct
in6_addr
);
:
sizeof
(
struct
in6_addr
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
...
@@ -1054,7 +1066,7 @@ static int ip_addr_add(int family, int ifindex,
...
@@ -1054,7 +1066,7 @@ static int ip_addr_add(int family, int ifindex,
goto
out
;
goto
out
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_ACK
|
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
;
NLM_F_ACK
|
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWADDR
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWADDR
;
ifa
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifaddrmsg
));
ifa
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifaddrmsg
));
...
@@ -1075,7 +1087,7 @@ static int ip_addr_add(int family, int ifindex,
...
@@ -1075,7 +1087,7 @@ static int ip_addr_add(int family, int ifindex,
if
(
nla_put_buffer
(
nlmsg
,
IFA_BROADCAST
,
bcast
,
addrlen
))
if
(
nla_put_buffer
(
nlmsg
,
IFA_BROADCAST
,
bcast
,
addrlen
))
goto
out
;
goto
out
;
/* TODO
: multicast, anycast with ipv6 */
/* TODO: multicast, anycast with ipv6 */
err
=
-
EPROTONOSUPPORT
;
err
=
-
EPROTONOSUPPORT
;
if
(
family
==
AF_INET6
&&
if
(
family
==
AF_INET6
&&
(
memcmp
(
bcast
,
&
in6addr_any
,
sizeof
(
in6addr_any
))
||
(
memcmp
(
bcast
,
&
in6addr_any
,
sizeof
(
in6addr_any
))
||
...
@@ -1091,48 +1103,52 @@ out:
...
@@ -1091,48 +1103,52 @@ out:
}
}
int
lxc_ipv6_addr_add
(
int
ifindex
,
struct
in6_addr
*
addr
,
int
lxc_ipv6_addr_add
(
int
ifindex
,
struct
in6_addr
*
addr
,
struct
in6_addr
*
mcast
,
struct
in6_addr
*
mcast
,
struct
in6_addr
*
acast
,
struct
in6_addr
*
acast
,
int
prefix
)
int
prefix
)
{
{
return
ip_addr_add
(
AF_INET6
,
ifindex
,
addr
,
mcast
,
acast
,
prefix
);
return
ip_addr_add
(
AF_INET6
,
ifindex
,
addr
,
mcast
,
acast
,
prefix
);
}
}
int
lxc_ipv4_addr_add
(
int
ifindex
,
struct
in_addr
*
addr
,
int
lxc_ipv4_addr_add
(
int
ifindex
,
struct
in_addr
*
addr
,
struct
in_addr
*
bcast
,
struct
in_addr
*
bcast
,
int
prefix
)
int
prefix
)
{
{
return
ip_addr_add
(
AF_INET
,
ifindex
,
addr
,
bcast
,
NULL
,
prefix
);
return
ip_addr_add
(
AF_INET
,
ifindex
,
addr
,
bcast
,
NULL
,
prefix
);
}
}
/* Find an IFA_LOCAL (or IFA_ADDRESS if not IFA_LOCAL is present)
/* Find an IFA_LOCAL (or IFA_ADDRESS if not IFA_LOCAL is present) address from
* address from the given RTM_NEWADDR message. Allocates memory for the
* the given RTM_NEWADDR message. Allocates memory for the address and stores
* address and stores that pointer in *res (so res should be an
* that pointer in *res (so res should be an in_addr** or in6_addr**).
* in_addr** or in6_addr**).
*/
*/
static
int
ifa_get_local_ip
(
int
family
,
struct
nlmsghdr
*
msg
,
void
**
res
)
{
static
int
ifa_get_local_ip
(
int
family
,
struct
nlmsghdr
*
msg
,
void
**
res
)
{
int
addrlen
;
struct
ifaddrmsg
*
ifa
=
NLMSG_DATA
(
msg
);
struct
ifaddrmsg
*
ifa
=
NLMSG_DATA
(
msg
);
struct
rtattr
*
rta
=
IFA_RTA
(
ifa
);
struct
rtattr
*
rta
=
IFA_RTA
(
ifa
);
int
attr_len
=
NLMSG_PAYLOAD
(
msg
,
sizeof
(
struct
ifaddrmsg
));
int
attr_len
=
NLMSG_PAYLOAD
(
msg
,
sizeof
(
struct
ifaddrmsg
));
int
addrlen
;
if
(
ifa
->
ifa_family
!=
family
)
if
(
ifa
->
ifa_family
!=
family
)
return
0
;
return
0
;
addrlen
=
family
==
AF_INET
?
sizeof
(
struct
in_addr
)
:
addrlen
=
family
==
AF_INET
?
sizeof
(
struct
in_addr
)
sizeof
(
struct
in6_addr
);
:
sizeof
(
struct
in6_addr
);
/* Loop over the rtattr's in this message */
/* Loop over the rtattr's in this message */
while
(
RTA_OK
(
rta
,
attr_len
))
{
while
(
RTA_OK
(
rta
,
attr_len
))
{
/* Found a local address for the requested interface,
/* Found a local address for the requested interface,
* return it. */
* return it.
if
(
rta
->
rta_type
==
IFA_LOCAL
||
rta
->
rta_type
==
IFA_ADDRESS
)
{
*/
/* Sanity check. The family check above should
if
(
rta
->
rta_type
==
IFA_LOCAL
||
* make sure the address length is correct, but
rta
->
rta_type
==
IFA_ADDRESS
)
{
* check here just in case */
/* Sanity check. The family check above should make sure
* the address length is correct, but check here just in
* case.
*/
if
(
RTA_PAYLOAD
(
rta
)
!=
addrlen
)
if
(
RTA_PAYLOAD
(
rta
)
!=
addrlen
)
return
-
1
;
return
-
1
;
/* We might have found an IFA_ADDRESS before,
/* We might have found an IFA_ADDRESS before, which we
* which we now overwrite with an IFA_LOCAL. */
* now overwrite with an IFA_LOCAL.
*/
if
(
!*
res
)
{
if
(
!*
res
)
{
*
res
=
malloc
(
addrlen
);
*
res
=
malloc
(
addrlen
);
if
(
!*
res
)
if
(
!*
res
)
...
@@ -1140,7 +1156,6 @@ static int ifa_get_local_ip(int family, struct nlmsghdr *msg, void** res) {
...
@@ -1140,7 +1156,6 @@ static int ifa_get_local_ip(int family, struct nlmsghdr *msg, void** res) {
}
}
memcpy
(
*
res
,
RTA_DATA
(
rta
),
addrlen
);
memcpy
(
*
res
,
RTA_DATA
(
rta
),
addrlen
);
if
(
rta
->
rta_type
==
IFA_LOCAL
)
if
(
rta
->
rta_type
==
IFA_LOCAL
)
break
;
break
;
}
}
...
@@ -1151,13 +1166,12 @@ static int ifa_get_local_ip(int family, struct nlmsghdr *msg, void** res) {
...
@@ -1151,13 +1166,12 @@ static int ifa_get_local_ip(int family, struct nlmsghdr *msg, void** res) {
static
int
ip_addr_get
(
int
family
,
int
ifindex
,
void
**
res
)
static
int
ip_addr_get
(
int
family
,
int
ifindex
,
void
**
res
)
{
{
struct
nl_handler
nlh
;
int
answer_len
,
err
;
struct
nlmsg
*
nlmsg
=
NULL
,
*
answer
=
NULL
;
struct
ifaddrmsg
*
ifa
;
struct
ifaddrmsg
*
ifa
;
struct
nl_handler
nlh
;
struct
nlmsghdr
*
msg
;
struct
nlmsghdr
*
msg
;
int
err
;
int
readmore
=
0
,
recv_len
=
0
;
int
recv_len
=
0
,
answer_len
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
int
readmore
=
0
;
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
...
@@ -1172,12 +1186,12 @@ static int ip_addr_get(int family, int ifindex, void **res)
...
@@ -1172,12 +1186,12 @@ static int ip_addr_get(int family, int ifindex, void **res)
if
(
!
answer
)
if
(
!
answer
)
goto
out
;
goto
out
;
/* Save the answer buffer length, since it will be overwritten
/* Save the answer buffer length, since it will be overwritten
on the
*
on the first receive (and we might need to receive more than
*
first receive (and we might need to receive more than once).
*
once. *
/
*/
answer_len
=
answer
->
nlmsghdr
->
nlmsg_len
;
answer_len
=
answer
->
nlmsghdr
->
nlmsg_len
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_ROOT
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_REQUEST
|
NLM_F_ROOT
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_GETADDR
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_GETADDR
;
ifa
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifaddrmsg
));
ifa
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
ifaddrmsg
));
...
@@ -1185,18 +1199,20 @@ static int ip_addr_get(int family, int ifindex, void **res)
...
@@ -1185,18 +1199,20 @@ static int ip_addr_get(int family, int ifindex, void **res)
goto
out
;
goto
out
;
ifa
->
ifa_family
=
family
;
ifa
->
ifa_family
=
family
;
/* Send the request for addresses, which returns all addresses
/* Send the request for addresses, which returns all addresses on all
* on all interfaces. */
* interfaces.
*/
err
=
netlink_send
(
&
nlh
,
nlmsg
);
err
=
netlink_send
(
&
nlh
,
nlmsg
);
if
(
err
<
0
)
if
(
err
<
0
)
goto
out
;
goto
out
;
do
{
do
{
/* Restore the answer buffer length, it might have been
/* Restore the answer buffer length, it might have been
* overwritten by a previous receive. */
* overwritten by a previous receive.
*/
answer
->
nlmsghdr
->
nlmsg_len
=
answer_len
;
answer
->
nlmsghdr
->
nlmsg_len
=
answer_len
;
/* Get the (next) batch of reply messages */
/* Get the (next) batch of reply messages
.
*/
err
=
netlink_rcv
(
&
nlh
,
answer
);
err
=
netlink_rcv
(
&
nlh
,
answer
);
if
(
err
<
0
)
if
(
err
<
0
)
goto
out
;
goto
out
;
...
@@ -1204,18 +1220,19 @@ static int ip_addr_get(int family, int ifindex, void **res)
...
@@ -1204,18 +1220,19 @@ static int ip_addr_get(int family, int ifindex, void **res)
recv_len
=
err
;
recv_len
=
err
;
err
=
0
;
err
=
0
;
/* Satisfy the typing for the netlink macros */
/* Satisfy the typing for the netlink macros
.
*/
msg
=
answer
->
nlmsghdr
;
msg
=
answer
->
nlmsghdr
;
while
(
NLMSG_OK
(
msg
,
recv_len
))
{
while
(
NLMSG_OK
(
msg
,
recv_len
))
{
/* Stop reading if we see an error message */
/* Stop reading if we see an error message
.
*/
if
(
msg
->
nlmsg_type
==
NLMSG_ERROR
)
{
if
(
msg
->
nlmsg_type
==
NLMSG_ERROR
)
{
struct
nlmsgerr
*
errmsg
=
(
struct
nlmsgerr
*
)
NLMSG_DATA
(
msg
);
struct
nlmsgerr
*
errmsg
=
(
struct
nlmsgerr
*
)
NLMSG_DATA
(
msg
);
err
=
errmsg
->
error
;
err
=
errmsg
->
error
;
goto
out
;
goto
out
;
}
}
/* Stop reading if we see a NLMSG_DONE message */
/* Stop reading if we see a NLMSG_DONE message
.
*/
if
(
msg
->
nlmsg_type
==
NLMSG_DONE
)
{
if
(
msg
->
nlmsg_type
==
NLMSG_DONE
)
{
readmore
=
0
;
readmore
=
0
;
break
;
break
;
...
@@ -1233,22 +1250,24 @@ static int ip_addr_get(int family, int ifindex, void **res)
...
@@ -1233,22 +1250,24 @@ static int ip_addr_get(int family, int ifindex, void **res)
goto
out
;
goto
out
;
}
}
/* Found a result, stop searching */
/* Found a result, stop searching
.
*/
if
(
*
res
)
if
(
*
res
)
goto
out
;
goto
out
;
}
}
/* Keep reading more data from the socket if the
/* Keep reading more data from the socket if the last
* last message had the NLF_F_MULTI flag set */
* message had the NLF_F_MULTI flag set.
*/
readmore
=
(
msg
->
nlmsg_flags
&
NLM_F_MULTI
);
readmore
=
(
msg
->
nlmsg_flags
&
NLM_F_MULTI
);
/* Look at the next message received in this buffer */
/* Look at the next message received in this buffer
.
*/
msg
=
NLMSG_NEXT
(
msg
,
recv_len
);
msg
=
NLMSG_NEXT
(
msg
,
recv_len
);
}
}
}
while
(
readmore
);
}
while
(
readmore
);
/* If we end up here, we didn't find any result, so signal an
/* If we end up here, we didn't find any result, so signal an
* error */
* error.
*/
err
=
-
1
;
err
=
-
1
;
out:
out:
...
@@ -1260,24 +1279,23 @@ out:
...
@@ -1260,24 +1279,23 @@ out:
int
lxc_ipv6_addr_get
(
int
ifindex
,
struct
in6_addr
**
res
)
int
lxc_ipv6_addr_get
(
int
ifindex
,
struct
in6_addr
**
res
)
{
{
return
ip_addr_get
(
AF_INET6
,
ifindex
,
(
void
**
)
res
);
return
ip_addr_get
(
AF_INET6
,
ifindex
,
(
void
**
)
res
);
}
}
int
lxc_ipv4_addr_get
(
int
ifindex
,
struct
in_addr
**
res
)
int
lxc_ipv4_addr_get
(
int
ifindex
,
struct
in_addr
**
res
)
{
{
return
ip_addr_get
(
AF_INET
,
ifindex
,
(
void
**
)
res
);
return
ip_addr_get
(
AF_INET
,
ifindex
,
(
void
**
)
res
);
}
}
static
int
ip_gateway_add
(
int
family
,
int
ifindex
,
void
*
gw
)
static
int
ip_gateway_add
(
int
family
,
int
ifindex
,
void
*
gw
)
{
{
int
addrlen
,
err
;
struct
nl_handler
nlh
;
struct
nl_handler
nlh
;
struct
nlmsg
*
nlmsg
=
NULL
,
*
answer
=
NULL
;
struct
rtmsg
*
rt
;
struct
rtmsg
*
rt
;
int
addrlen
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
int
err
;
addrlen
=
family
==
AF_INET
?
sizeof
(
struct
in_addr
)
:
addrlen
=
family
==
AF_INET
?
sizeof
(
struct
in_addr
)
sizeof
(
struct
in6_addr
);
:
sizeof
(
struct
in6_addr
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
...
@@ -1293,7 +1311,7 @@ static int ip_gateway_add(int family, int ifindex, void *gw)
...
@@ -1293,7 +1311,7 @@ static int ip_gateway_add(int family, int ifindex, void *gw)
goto
out
;
goto
out
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_ACK
|
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
;
NLM_F_ACK
|
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWROUTE
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWROUTE
;
rt
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
rtmsg
));
rt
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
rtmsg
));
...
@@ -1312,7 +1330,8 @@ static int ip_gateway_add(int family, int ifindex, void *gw)
...
@@ -1312,7 +1330,8 @@ static int ip_gateway_add(int family, int ifindex, void *gw)
goto
out
;
goto
out
;
/* Adding the interface index enables the use of link-local
/* Adding the interface index enables the use of link-local
* addresses for the gateway */
* addresses for the gateway.
*/
if
(
nla_put_u32
(
nlmsg
,
RTA_OIF
,
ifindex
))
if
(
nla_put_u32
(
nlmsg
,
RTA_OIF
,
ifindex
))
goto
out
;
goto
out
;
...
@@ -1336,14 +1355,13 @@ int lxc_ipv6_gateway_add(int ifindex, struct in6_addr *gw)
...
@@ -1336,14 +1355,13 @@ int lxc_ipv6_gateway_add(int ifindex, struct in6_addr *gw)
static
int
ip_route_dest_add
(
int
family
,
int
ifindex
,
void
*
dest
)
static
int
ip_route_dest_add
(
int
family
,
int
ifindex
,
void
*
dest
)
{
{
int
addrlen
,
err
;
struct
nl_handler
nlh
;
struct
nl_handler
nlh
;
struct
nlmsg
*
nlmsg
=
NULL
,
*
answer
=
NULL
;
struct
rtmsg
*
rt
;
struct
rtmsg
*
rt
;
int
addrlen
;
struct
nlmsg
*
answer
=
NULL
,
*
nlmsg
=
NULL
;
int
err
;
addrlen
=
family
==
AF_INET
?
sizeof
(
struct
in_addr
)
:
addrlen
=
family
==
AF_INET
?
sizeof
(
struct
in_addr
)
sizeof
(
struct
in6_addr
);
:
sizeof
(
struct
in6_addr
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
if
(
err
)
if
(
err
)
...
@@ -1359,7 +1377,7 @@ static int ip_route_dest_add(int family, int ifindex, void *dest)
...
@@ -1359,7 +1377,7 @@ static int ip_route_dest_add(int family, int ifindex, void *dest)
goto
out
;
goto
out
;
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
nlmsg
->
nlmsghdr
->
nlmsg_flags
=
NLM_F_ACK
|
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
;
NLM_F_ACK
|
NLM_F_REQUEST
|
NLM_F_CREATE
|
NLM_F_EXCL
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWROUTE
;
nlmsg
->
nlmsghdr
->
nlmsg_type
=
RTM_NEWROUTE
;
rt
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
rtmsg
));
rt
=
nlmsg_reserve
(
nlmsg
,
sizeof
(
struct
rtmsg
));
...
@@ -1370,7 +1388,7 @@ static int ip_route_dest_add(int family, int ifindex, void *dest)
...
@@ -1370,7 +1388,7 @@ static int ip_route_dest_add(int family, int ifindex, void *dest)
rt
->
rtm_scope
=
RT_SCOPE_LINK
;
rt
->
rtm_scope
=
RT_SCOPE_LINK
;
rt
->
rtm_protocol
=
RTPROT_BOOT
;
rt
->
rtm_protocol
=
RTPROT_BOOT
;
rt
->
rtm_type
=
RTN_UNICAST
;
rt
->
rtm_type
=
RTN_UNICAST
;
rt
->
rtm_dst_len
=
addrlen
*
8
;
rt
->
rtm_dst_len
=
addrlen
*
8
;
err
=
-
EINVAL
;
err
=
-
EINVAL
;
if
(
nla_put_buffer
(
nlmsg
,
RTA_DST
,
dest
,
addrlen
))
if
(
nla_put_buffer
(
nlmsg
,
RTA_DST
,
dest
,
addrlen
))
...
@@ -1397,12 +1415,19 @@ int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest)
...
@@ -1397,12 +1415,19 @@ int lxc_ipv6_dest_add(int ifindex, struct in6_addr *dest)
static
bool
is_ovs_bridge
(
const
char
*
bridge
)
static
bool
is_ovs_bridge
(
const
char
*
bridge
)
{
{
char
brdirname
[
22
+
IFNAMSIZ
+
1
]
=
{
0
}
;
int
ret
;
struct
stat
sb
;
struct
stat
sb
;
char
brdirname
[
22
+
IFNAMSIZ
+
1
]
=
{
0
};
ret
=
snprintf
(
brdirname
,
22
+
IFNAMSIZ
+
1
,
"/sys/class/net/%s/bridge"
,
bridge
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
22
+
IFNAMSIZ
+
1
)
return
false
;
snprintf
(
brdirname
,
22
+
IFNAMSIZ
+
1
,
"/sys/class/net/%s/bridge"
,
bridge
);
ret
=
stat
(
brdirname
,
&
sb
);
if
(
stat
(
brdirname
,
&
sb
)
==
-
1
&&
errno
==
ENOENT
)
if
(
ret
<
0
&&
errno
==
ENOENT
)
return
true
;
return
true
;
return
false
;
return
false
;
}
}
...
@@ -1432,7 +1457,8 @@ static void ovs_cleanup_nic(const char *lxcpath, const char *name,
...
@@ -1432,7 +1457,8 @@ static void ovs_cleanup_nic(const char *lxcpath, const char *name,
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
static
int
attach_to_ovs_bridge
(
const
char
*
lxcpath
,
const
char
*
name
,
const
char
*
bridge
,
const
char
*
nic
)
static
int
attach_to_ovs_bridge
(
const
char
*
lxcpath
,
const
char
*
name
,
const
char
*
bridge
,
const
char
*
nic
)
{
{
pid_t
pid
;
pid_t
pid
;
char
*
cmd
;
char
*
cmd
;
...
@@ -1446,31 +1472,34 @@ static int attach_to_ovs_bridge(const char *lxcpath, const char *name, const cha
...
@@ -1446,31 +1472,34 @@ static int attach_to_ovs_bridge(const char *lxcpath, const char *name, const cha
pid
=
fork
();
pid
=
fork
();
if
(
pid
<
0
)
if
(
pid
<
0
)
return
-
1
;
return
-
1
;
if
(
pid
>
0
)
{
if
(
pid
>
0
)
{
ret
=
wait_for_pid
(
pid
);
ret
=
wait_for_pid
(
pid
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
pid
=
fork
();
pid
=
fork
();
if
(
pid
<
0
)
if
(
pid
<
0
)
return
-
1
;
/* how to properly recover? */
return
-
1
;
if
(
pid
>
0
)
if
(
pid
>
0
)
return
0
;
return
0
;
ovs_cleanup_nic
(
lxcpath
,
name
,
bridge
,
nic
);
ovs_cleanup_nic
(
lxcpath
,
name
,
bridge
,
nic
);
exit
(
0
);
exit
(
EXIT_SUCCESS
);
}
}
if
(
execlp
(
"ovs-vsctl"
,
"ovs-vsctl"
,
"add-port"
,
bridge
,
nic
,
(
char
*
)
NULL
))
execlp
(
"ovs-vsctl"
,
"ovs-vsctl"
,
"add-port"
,
bridge
,
nic
,
(
char
*
)
NULL
);
exit
(
1
);
exit
(
EXIT_FAILURE
);
/* not reached */
exit
(
1
);
}
}
/* There is a lxc_bridge_attach, but no need of a bridge detach as automatically
/* There is a lxc_bridge_attach, but no need of a bridge detach as automatically
* done by kernel when a netdev is deleted.
* done by kernel when a netdev is deleted.
*/
*/
int
lxc_bridge_attach
(
const
char
*
lxcpath
,
const
char
*
name
,
const
char
*
bridge
,
const
char
*
ifname
)
int
lxc_bridge_attach
(
const
char
*
lxcpath
,
const
char
*
name
,
const
char
*
bridge
,
const
char
*
ifname
)
{
{
int
fd
,
index
,
err
;
int
err
,
fd
,
index
;
struct
ifreq
ifr
;
struct
ifreq
ifr
;
if
(
strlen
(
ifname
)
>=
IFNAMSIZ
)
if
(
strlen
(
ifname
)
>=
IFNAMSIZ
)
...
@@ -1487,8 +1516,8 @@ int lxc_bridge_attach(const char *lxcpath, const char *name, const char *bridge,
...
@@ -1487,8 +1516,8 @@ int lxc_bridge_attach(const char *lxcpath, const char *name, const char *bridge,
if
(
fd
<
0
)
if
(
fd
<
0
)
return
-
errno
;
return
-
errno
;
strncpy
(
ifr
.
ifr_name
,
bridge
,
IFNAMSIZ
-
1
);
strncpy
(
ifr
.
ifr_name
,
bridge
,
IFNAMSIZ
-
1
);
ifr
.
ifr_name
[
IFNAMSIZ
-
1
]
=
'\0'
;
ifr
.
ifr_name
[
IFNAMSIZ
-
1
]
=
'\0'
;
ifr
.
ifr_ifindex
=
index
;
ifr
.
ifr_ifindex
=
index
;
err
=
ioctl
(
fd
,
SIOCBRADDIF
,
&
ifr
);
err
=
ioctl
(
fd
,
SIOCBRADDIF
,
&
ifr
);
close
(
fd
);
close
(
fd
);
...
@@ -1498,7 +1527,7 @@ int lxc_bridge_attach(const char *lxcpath, const char *name, const char *bridge,
...
@@ -1498,7 +1527,7 @@ int lxc_bridge_attach(const char *lxcpath, const char *name, const char *bridge,
return
err
;
return
err
;
}
}
static
const
char
*
const
lxc_network_types
[
LXC_NET_MAXCONFTYPE
+
1
]
=
{
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"
,
...
@@ -1511,40 +1540,40 @@ const char *lxc_net_type_to_str(int type)
...
@@ -1511,40 +1540,40 @@ const char *lxc_net_type_to_str(int type)
{
{
if
(
type
<
0
||
type
>
LXC_NET_MAXCONFTYPE
)
if
(
type
<
0
||
type
>
LXC_NET_MAXCONFTYPE
)
return
NULL
;
return
NULL
;
return
lxc_network_types
[
type
];
return
lxc_network_types
[
type
];
}
}
static
const
char
padchar
[]
=
static
const
char
padchar
[]
=
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
;
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
;
char
*
lxc_mkifname
(
char
*
template
)
char
*
lxc_mkifname
(
char
*
template
)
{
{
char
*
name
=
NULL
;
int
ifexists
=
0
;
size_t
i
=
0
;
size_t
i
=
0
;
FILE
*
urandom
;
char
*
name
=
NULL
;
unsigned
int
seed
;
unsigned
int
seed
;
struct
ifaddrs
*
ifaddr
,
*
ifa
;
FILE
*
urandom
;
int
ifexists
=
0
;
struct
ifaddrs
*
ifa
,
*
ifaddr
;
/* Get all the network interfaces */
/* Get all the network interfaces
.
*/
getifaddrs
(
&
ifaddr
);
getifaddrs
(
&
ifaddr
);
/* Initialize the random number generator */
/* Initialize the random number generator
.
*/
urandom
=
fopen
(
"/dev/urandom"
,
"r"
);
urandom
=
fopen
(
"/dev/urandom"
,
"r"
);
if
(
urandom
!=
NULL
)
{
if
(
urandom
!=
NULL
)
{
if
(
fread
(
&
seed
,
sizeof
(
seed
),
1
,
urandom
)
<=
0
)
if
(
fread
(
&
seed
,
sizeof
(
seed
),
1
,
urandom
)
<=
0
)
seed
=
time
(
0
);
seed
=
time
(
0
);
fclose
(
urandom
);
fclose
(
urandom
);
}
}
else
{
else
seed
=
time
(
0
);
seed
=
time
(
0
);
}
#ifndef HAVE_RAND_R
#ifndef HAVE_RAND_R
srand
(
seed
);
srand
(
seed
);
#endif
#endif
/* Generate random names until we find one that doesn't exist */
/* Generate random names until we find one that doesn't exist
.
*/
while
(
1
)
{
while
(
true
)
{
ifexists
=
0
;
ifexists
=
0
;
name
=
strdup
(
template
);
name
=
strdup
(
template
);
...
@@ -1554,7 +1583,8 @@ char *lxc_mkifname(char *template)
...
@@ -1554,7 +1583,8 @@ char *lxc_mkifname(char *template)
for
(
i
=
0
;
i
<
strlen
(
name
);
i
++
)
{
for
(
i
=
0
;
i
<
strlen
(
name
);
i
++
)
{
if
(
name
[
i
]
==
'X'
)
{
if
(
name
[
i
]
==
'X'
)
{
#ifdef HAVE_RAND_R
#ifdef HAVE_RAND_R
name
[
i
]
=
padchar
[
rand_r
(
&
seed
)
%
(
strlen
(
padchar
)
-
1
)];
name
[
i
]
=
padchar
[
rand_r
(
&
seed
)
%
(
strlen
(
padchar
)
-
1
)];
#else
#else
name
[
i
]
=
padchar
[
rand
()
%
(
strlen
(
padchar
)
-
1
)];
name
[
i
]
=
padchar
[
rand
()
%
(
strlen
(
padchar
)
-
1
)];
#endif
#endif
...
@@ -1580,15 +1610,17 @@ char *lxc_mkifname(char *template)
...
@@ -1580,15 +1610,17 @@ char *lxc_mkifname(char *template)
int
setup_private_host_hw_addr
(
char
*
veth1
)
int
setup_private_host_hw_addr
(
char
*
veth1
)
{
{
int
err
,
sockfd
;
struct
ifreq
ifr
;
struct
ifreq
ifr
;
int
err
;
int
sockfd
;
sockfd
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
);
sockfd
=
socket
(
AF_INET
,
SOCK_DGRAM
,
0
);
if
(
sockfd
<
0
)
if
(
sockfd
<
0
)
return
-
errno
;
return
-
errno
;
snprintf
((
char
*
)
ifr
.
ifr_name
,
IFNAMSIZ
,
"%s"
,
veth1
);
err
=
snprintf
((
char
*
)
ifr
.
ifr_name
,
IFNAMSIZ
,
"%s"
,
veth1
);
if
(
err
<
0
||
(
size_t
)
err
>=
IFNAMSIZ
)
return
-
E2BIG
;
err
=
ioctl
(
sockfd
,
SIOCGIFHWADDR
,
&
ifr
);
err
=
ioctl
(
sockfd
,
SIOCGIFHWADDR
,
&
ifr
);
if
(
err
<
0
)
{
if
(
err
<
0
)
{
close
(
sockfd
);
close
(
sockfd
);
...
...
src/lxc/network.h
View file @
ebc73a67
...
@@ -23,64 +23,50 @@
...
@@ -23,64 +23,50 @@
#ifndef __LXC_NETWORK_H
#ifndef __LXC_NETWORK_H
#define __LXC_NETWORK_H
#define __LXC_NETWORK_H
/*
#include <stdio.h>
* Convert a string mac address to a socket structure
#include <unistd.h>
*/
#include <arpa/inet.h>
#include <sys/socket.h>
/* Convert a string mac address to a socket structure. */
extern
int
lxc_convert_mac
(
char
*
macaddr
,
struct
sockaddr
*
sockaddr
);
extern
int
lxc_convert_mac
(
char
*
macaddr
,
struct
sockaddr
*
sockaddr
);
/*
/* Move a device between namespaces. */
* Move a device between namespaces
*/
extern
int
lxc_netdev_move_by_index
(
int
ifindex
,
pid_t
pid
,
const
char
*
ifname
);
extern
int
lxc_netdev_move_by_index
(
int
ifindex
,
pid_t
pid
,
const
char
*
ifname
);
extern
int
lxc_netdev_move_by_name
(
const
char
*
ifname
,
pid_t
pid
,
const
char
*
newname
);
extern
int
lxc_netdev_move_by_name
(
const
char
*
ifname
,
pid_t
pid
,
const
char
*
newname
);
/*
/* Delete a network device. */
* Delete a network device
*/
extern
int
lxc_netdev_delete_by_name
(
const
char
*
name
);
extern
int
lxc_netdev_delete_by_name
(
const
char
*
name
);
extern
int
lxc_netdev_delete_by_index
(
int
ifindex
);
extern
int
lxc_netdev_delete_by_index
(
int
ifindex
);
/*
/* Change the device name. */
* Change the device name
*/
extern
int
lxc_netdev_rename_by_name
(
const
char
*
oldname
,
const
char
*
newname
);
extern
int
lxc_netdev_rename_by_name
(
const
char
*
oldname
,
const
char
*
newname
);
extern
int
lxc_netdev_rename_by_index
(
int
ifindex
,
const
char
*
newname
);
extern
int
lxc_netdev_rename_by_index
(
int
ifindex
,
const
char
*
newname
);
extern
int
netdev_set_flag
(
const
char
*
name
,
int
flag
);
extern
int
netdev_set_flag
(
const
char
*
name
,
int
flag
);
/*
/* Set the device network up or down. */
* Set the device network up or down
*/
extern
int
lxc_netdev_isup
(
const
char
*
name
);
extern
int
lxc_netdev_isup
(
const
char
*
name
);
extern
int
lxc_netdev_up
(
const
char
*
name
);
extern
int
lxc_netdev_up
(
const
char
*
name
);
extern
int
lxc_netdev_down
(
const
char
*
name
);
extern
int
lxc_netdev_down
(
const
char
*
name
);
/*
/* Change the mtu size for the specified device. */
* Change the mtu size for the specified device
*/
extern
int
lxc_netdev_set_mtu
(
const
char
*
name
,
int
mtu
);
extern
int
lxc_netdev_set_mtu
(
const
char
*
name
,
int
mtu
);
/*
/* Create a virtual network devices. */
* Create a virtual network devices
*/
extern
int
lxc_veth_create
(
const
char
*
name1
,
const
char
*
name2
);
extern
int
lxc_veth_create
(
const
char
*
name1
,
const
char
*
name2
);
extern
int
lxc_macvlan_create
(
const
char
*
master
,
const
char
*
name
,
int
mode
);
extern
int
lxc_macvlan_create
(
const
char
*
master
,
const
char
*
name
,
int
mode
);
extern
int
lxc_vlan_create
(
const
char
*
master
,
const
char
*
name
,
unsigned
short
vid
);
extern
int
lxc_vlan_create
(
const
char
*
master
,
const
char
*
name
,
unsigned
short
vid
);
/*
/* Activate forwarding.*/
* Activate forwarding
*/
extern
int
lxc_ip_forward_on
(
const
char
*
name
,
int
family
);
extern
int
lxc_ip_forward_on
(
const
char
*
name
,
int
family
);
/*
/* Disable forwarding. */
* Disable forwarding
*/
extern
int
lxc_ip_forward_off
(
const
char
*
name
,
int
family
);
extern
int
lxc_ip_forward_off
(
const
char
*
name
,
int
family
);
/*
/* Set ip address. */
* Set ip address
*/
extern
int
lxc_ipv6_addr_add
(
int
ifindex
,
struct
in6_addr
*
addr
,
extern
int
lxc_ipv6_addr_add
(
int
ifindex
,
struct
in6_addr
*
addr
,
struct
in6_addr
*
mcast
,
struct
in6_addr
*
mcast
,
struct
in6_addr
*
acast
,
int
prefix
);
struct
in6_addr
*
acast
,
int
prefix
);
...
@@ -88,57 +74,41 @@ extern int lxc_ipv6_addr_add(int ifindex, struct in6_addr *addr,
...
@@ -88,57 +74,41 @@ extern int lxc_ipv6_addr_add(int ifindex, struct in6_addr *addr,
extern
int
lxc_ipv4_addr_add
(
int
ifindex
,
struct
in_addr
*
addr
,
extern
int
lxc_ipv4_addr_add
(
int
ifindex
,
struct
in_addr
*
addr
,
struct
in_addr
*
bcast
,
int
prefix
);
struct
in_addr
*
bcast
,
int
prefix
);
/*
/* Get ip address. */
* Get ip address
*/
extern
int
lxc_ipv4_addr_get
(
int
ifindex
,
struct
in_addr
**
res
);
extern
int
lxc_ipv4_addr_get
(
int
ifindex
,
struct
in_addr
**
res
);
extern
int
lxc_ipv6_addr_get
(
int
ifindex
,
struct
in6_addr
**
res
);
extern
int
lxc_ipv6_addr_get
(
int
ifindex
,
struct
in6_addr
**
res
);
/*
/* Set a destination route to an interface. */
* Set a destination route to an interface
*/
extern
int
lxc_ipv4_dest_add
(
int
ifindex
,
struct
in_addr
*
dest
);
extern
int
lxc_ipv4_dest_add
(
int
ifindex
,
struct
in_addr
*
dest
);
extern
int
lxc_ipv6_dest_add
(
int
ifindex
,
struct
in6_addr
*
dest
);
extern
int
lxc_ipv6_dest_add
(
int
ifindex
,
struct
in6_addr
*
dest
);
/*
/* Set default route. */
* Set default route.
*/
extern
int
lxc_ipv4_gateway_add
(
int
ifindex
,
struct
in_addr
*
gw
);
extern
int
lxc_ipv4_gateway_add
(
int
ifindex
,
struct
in_addr
*
gw
);
extern
int
lxc_ipv6_gateway_add
(
int
ifindex
,
struct
in6_addr
*
gw
);
extern
int
lxc_ipv6_gateway_add
(
int
ifindex
,
struct
in6_addr
*
gw
);
/*
/* Attach an interface to the bridge. */
* Attach an interface to the bridge
extern
int
lxc_bridge_attach
(
const
char
*
lxcpath
,
const
char
*
name
,
*/
const
char
*
bridge
,
const
char
*
ifname
);
extern
int
lxc_bridge_attach
(
const
char
*
lxcpath
,
const
char
*
name
,
const
char
*
bridge
,
const
char
*
ifname
);
/*
/* Create default gateway. */
* Create default gateway
*/
extern
int
lxc_route_create_default
(
const
char
*
addr
,
const
char
*
ifname
,
extern
int
lxc_route_create_default
(
const
char
*
addr
,
const
char
*
ifname
,
int
gateway
);
int
gateway
);
/*
/* Delete default gateway. */
* Delete default gateway
*/
extern
int
lxc_route_delete_default
(
const
char
*
addr
,
const
char
*
ifname
,
extern
int
lxc_route_delete_default
(
const
char
*
addr
,
const
char
*
ifname
,
int
gateway
);
int
gateway
);
/*
/* Activate neighbor proxying. */
* Activate neighbor proxying
*/
extern
int
lxc_neigh_proxy_on
(
const
char
*
name
,
int
family
);
extern
int
lxc_neigh_proxy_on
(
const
char
*
name
,
int
family
);
/*
/* Disable neighbor proxying. */
* Disable neighbor proxying
*/
extern
int
lxc_neigh_proxy_off
(
const
char
*
name
,
int
family
);
extern
int
lxc_neigh_proxy_off
(
const
char
*
name
,
int
family
);
/*
/* Generate a new unique network interface name. */
* Generate a new unique network interface name
*/
extern
char
*
lxc_mkifname
(
char
*
template
);
extern
char
*
lxc_mkifname
(
char
*
template
);
extern
const
char
*
lxc_net_type_to_str
(
int
type
);
extern
const
char
*
lxc_net_type_to_str
(
int
type
);
extern
int
setup_private_host_hw_addr
(
char
*
veth1
);
extern
int
setup_private_host_hw_addr
(
char
*
veth1
);
extern
int
netdev_get_mtu
(
int
ifindex
);
extern
int
netdev_get_mtu
(
int
ifindex
);
#endif
#endif
/* __LXC_NETWORK_H */
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