@@ -125,7 +125,7 @@ struct link_util {
const char *id;
int maxattr;
int (*parse_opt)(struct link_util *, int, char **,
- struct nlmsghdr *);
+ struct nlmsghdr *, int *);
void (*print_opt)(struct link_util *, FILE *,
struct rtattr *[]);
void (*print_xstats)(struct link_util *, FILE *,
@@ -139,7 +139,7 @@ struct link_util {
struct link_util *get_link_kind(const char *kind);
-int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type);
+int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type, int *netns_fd);
/* iplink_bridge.c */
void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len);
@@ -522,7 +522,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp,
return 0;
}
-int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
+int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type, int *netns_fd)
{
bool move_netns = false;
char *name = NULL;
@@ -622,9 +622,11 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
if (netns != -1)
duparg("netns", *argv);
netns = netns_get_fd(*argv);
- if (netns >= 0)
+ if (netns >= 0) {
+ *netns_fd = netns;
addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_FD,
&netns, 4);
+ }
else if (get_integer(&netns, *argv, 0) == 0)
addattr_l(&req->n, sizeof(*req),
IFLA_NET_NS_PID, &netns, 4);
@@ -1034,9 +1036,10 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
.n.nlmsg_type = cmd,
.i.ifi_family = preferred_family,
};
+ int netns_fd = -1, netns_fd2 = -1;
int ret;
- ret = iplink_parse(argc, argv, &req, &type);
+ ret = iplink_parse(argc, argv, &req, &type, &netns_fd);
if (ret < 0)
return ret;
@@ -1064,7 +1067,7 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
data = addattr_nest(&req.n, sizeof(req), iflatype);
- if (lu->parse_opt(lu, argc, argv, &req.n))
+ if (lu->parse_opt(lu, argc, argv, &req.n, &netns_fd2))
return -1;
addattr_nest_end(&req.n, data);
@@ -1088,6 +1091,11 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
else
ret = rtnl_talk(&rth, &req.n, NULL);
+ if (netns_fd >= 0)
+ close(netns_fd);
+ if (netns_fd2 >= 0)
+ close(netns_fd2);
+
if (ret)
return -2;
@@ -55,7 +55,7 @@ static void check_duparg(__u64 *attrs, int type, const char *key,
}
static int amt_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
unsigned int mode, max_tunnels;
inet_prefix saddr, daddr;
@@ -46,7 +46,7 @@ static void check_duparg(__u64 *attrs, int type, const char *key,
}
static int bareudp_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
bool multiproto = false;
__u16 srcportmin = 0;
@@ -29,7 +29,7 @@ static void explain(void)
}
static int batadv_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
while (argc > 0) {
if (matches(*argv, "ra") == 0) {
@@ -174,7 +174,7 @@ static void explain(void)
}
static int bond_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
__u8 mode, use_carrier, primary_reselect, fail_over_mac;
__u8 xmit_hash_policy, num_peer_notif, all_slaves_active;
@@ -148,7 +148,7 @@ static void bond_slave_print_opt(struct link_util *lu, FILE *f, struct rtattr *t
}
static int bond_slave_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
__u16 queue_id;
int prio;
@@ -81,7 +81,7 @@ void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len)
}
static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
struct br_boolopt_multi bm = {};
__u32 val;
@@ -327,7 +327,7 @@ static void bridge_slave_parse_on_off(char *arg_name, char *arg_val,
}
static int bridge_slave_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
__u8 state;
__u16 priority;
@@ -124,7 +124,7 @@ static void print_ctrlmode(enum output_type t, __u32 flags, const char* key)
}
static int can_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
struct can_bittiming bt = {}, dbt = {};
struct can_ctrlmode cm = { 0 };
@@ -12,7 +12,7 @@ static void print_usage(FILE *f)
}
static int dsa_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
while (argc > 0) {
if (strcmp(*argv, "conduit") == 0 ||
@@ -54,7 +54,7 @@ static void check_duparg(__u64 *attrs, int type, const char *key,
}
static int geneve_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
inet_prefix daddr;
__u32 vni = 0;
@@ -32,7 +32,7 @@ static void check_duparg(__u32 *attrs, int type, const char *key,
}
static int gtp_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
__u32 attrs = 0;
@@ -45,7 +45,7 @@ static void usage(void)
}
static int hsr_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
int ifindex;
unsigned char multicast_spec;
@@ -38,7 +38,7 @@ static int mode_arg(void)
}
static int ipoib_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
__u16 pkey, mode, umcast;
@@ -26,7 +26,7 @@ static void print_explain(struct link_util *lu, FILE *f)
}
static int ipvlan_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
__u16 flags = 0;
bool mflag_given = false;
@@ -75,7 +75,7 @@ static int bclim_arg(const char *arg)
}
static int macvlan_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
__u32 mode = 0;
__u16 flags = 0;
@@ -38,7 +38,7 @@ static void explain(struct link_util *lu, FILE *f)
}
static int netkit_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
__u32 ifi_flags, ifi_change, ifi_index;
struct ifinfomsg *ifm, *peer_ifm;
@@ -97,7 +97,8 @@ static int netkit_parse_opt(struct link_util *lu, int argc, char **argv,
if (seen_peer) {
data = addattr_nest(n, 1024, IFLA_NETKIT_PEER_INFO);
n->nlmsg_len += sizeof(struct ifinfomsg);
- err = iplink_parse(argc, argv, (struct iplink_req *)n, &type);
+ err = iplink_parse(argc, argv, (struct iplink_req *)n, &type,
+ netns_fd);
if (err < 0)
return err;
if (type)
@@ -27,7 +27,7 @@ static void explain(void)
}
static int rmnet_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
__u16 mux_id;
@@ -73,7 +73,7 @@ static int vlan_parse_qos_map(int *argcp, char ***argvp, struct nlmsghdr *n,
}
static int vlan_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
struct ifla_vlan_flags flags = { 0 };
__u16 id, proto;
@@ -26,7 +26,7 @@ static void explain(void)
}
static int vrf_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
while (argc > 0) {
if (matches(*argv, "table") == 0) {
@@ -27,7 +27,7 @@ static void usage(void)
}
static int vxcan_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
char *type = NULL;
int err;
@@ -52,7 +52,8 @@ static int vxcan_parse_opt(struct link_util *lu, int argc, char **argv,
n->nlmsg_len += sizeof(struct ifinfomsg);
- err = iplink_parse(argc - 1, argv + 1, (struct iplink_req *)n, &type);
+ err = iplink_parse(argc - 1, argv + 1, (struct iplink_req *)n, &type,
+ netns_fd);
if (err < 0)
return err;
@@ -92,7 +92,7 @@ static void check_duparg(__u64 *attrs, int type, const char *key,
}
static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
inet_prefix saddr, daddr;
__u32 vni = 0;
@@ -22,7 +22,7 @@ static void explain(void)
}
static int wwan_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
while (argc > 0) {
if (matches(*argv, "linkid") == 0) {
@@ -1344,7 +1344,7 @@ static void usage(FILE *f)
}
static int macsec_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
int ret;
__u8 encoding_sa = 0xff;
@@ -63,7 +63,7 @@ static void gre_print_help(struct link_util *lu, int argc, char **argv, FILE *f)
}
static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
struct ifinfomsg *ifi = NLMSG_DATA(n);
struct {
@@ -66,7 +66,7 @@ static void gre_print_help(struct link_util *lu, int argc, char **argv, FILE *f)
}
static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
struct ifinfomsg *ifi = NLMSG_DATA(n);
struct {
@@ -59,7 +59,7 @@ static void ip6tunnel_print_help(struct link_util *lu, int argc, char **argv,
}
static int ip6tunnel_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
struct ifinfomsg *ifi = NLMSG_DATA(n);
struct {
@@ -60,7 +60,7 @@ static void iptunnel_print_help(struct link_util *lu, int argc, char **argv,
}
static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
struct ifinfomsg *ifi = NLMSG_DATA(n);
struct {
@@ -24,7 +24,7 @@ static void usage(void)
}
static int veth_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
char *type = NULL;
int err;
@@ -49,7 +49,8 @@ static int veth_parse_opt(struct link_util *lu, int argc, char **argv,
n->nlmsg_len += sizeof(struct ifinfomsg);
- err = iplink_parse(argc - 1, argv + 1, (struct iplink_req *)n, &type);
+ err = iplink_parse(argc - 1, argv + 1, (struct iplink_req *)n, &type,
+ netns_fd);
if (err < 0)
return err;
@@ -35,7 +35,7 @@ static void vti_print_help(struct link_util *lu, int argc, char **argv, FILE *f)
}
static int vti_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
struct ifinfomsg *ifi = NLMSG_DATA(n);
struct {
@@ -37,7 +37,7 @@ static void vti6_print_help(struct link_util *lu, int argc, char **argv,
}
static int vti6_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
struct ifinfomsg *ifi = NLMSG_DATA(n);
struct {
@@ -25,7 +25,7 @@ static void xfrm_print_help(struct link_util *lu, int argc, char **argv,
}
static int xfrm_parse_opt(struct link_util *lu, int argc, char **argv,
- struct nlmsghdr *n)
+ struct nlmsghdr *n, int *netns_fd)
{
unsigned int link = 0;
bool metadata = false;