]> git.proxmox.com Git - mirror_iproute2.git/blobdiff - ip/iplink.c
iplink_vxlan: take into account preferred_family creating vxlan device
[mirror_iproute2.git] / ip / iplink.c
index 29b7062f6aa4b2a86e8106b9781069ad2c221ecc..0ba5f1af766974bccb80526910f15c27bb3f840b 100644 (file)
@@ -85,7 +85,7 @@ void iplink_usage(void)
                "                         [ broadcast LLADDR ]\n"
                "                         [ mtu MTU ]\n"
                "                         [ netns { PID | NAME } ]\n"
-               "                         [ link-netnsid ID ]\n"
+               "                         [ link-netns NAME | link-netnsid ID ]\n"
                "                         [ alias NAME ]\n"
                "                         [ vf NUM [ mac LLADDR ]\n"
                "                                  [ vlan VLANID [ qos VLAN-QOS ] [ proto VLAN-PROTO ] ]\n"
@@ -121,7 +121,7 @@ void iplink_usage(void)
                        "          bridge | bond | team | ipoib | ip6tnl | ipip | sit | vxlan |\n"
                        "          gre | gretap | erspan | ip6gre | ip6gretap | ip6erspan |\n"
                        "          vti | nlmon | team_slave | bond_slave | ipvlan | geneve |\n"
-                       "          bridge_slave | vrf | macsec | netdevsim }\n");
+                       "          bridge_slave | vrf | macsec | netdevsim | rmnet }\n");
        }
        exit(-1);
 }
@@ -242,9 +242,10 @@ static int iplink_have_newlink(void)
 }
 #endif /* ! IPLINK_IOCTL_COMPAT */
 
-static int nl_get_ll_addr_len(unsigned int dev_index)
+static int nl_get_ll_addr_len(const char *ifname)
 {
        int len;
+       int dev_index = ll_name_to_index(ifname);
        struct iplink_req req = {
                .n = {
                        .nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
@@ -259,6 +260,9 @@ static int nl_get_ll_addr_len(unsigned int dev_index)
        struct nlmsghdr *answer;
        struct rtattr *tb[IFLA_MAX+1];
 
+       if (dev_index == 0)
+               return -1;
+
        if (rtnl_talk(&rth, &req.n, &answer) < 0)
                return -1;
 
@@ -337,7 +341,7 @@ static void iplink_parse_vf_vlan_info(int vf, int *argcp, char ***argvp,
 }
 
 static int iplink_parse_vf(int vf, int *argcp, char ***argvp,
-                          struct iplink_req *req, int dev_index)
+                          struct iplink_req *req, const char *dev)
 {
        char new_rate_api = 0, count = 0, override_legacy_rate = 0;
        struct ifla_vf_rate tivt;
@@ -373,7 +377,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp,
                NEXT_ARG();
                if (matches(*argv, "mac") == 0) {
                        struct ifla_vf_mac ivm = { 0 };
-                       int halen = nl_get_ll_addr_len(dev_index);
+                       int halen = nl_get_ll_addr_len(dev);
 
                        NEXT_ARG();
                        ivm.vf = vf;
@@ -542,7 +546,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp,
                int tmin, tmax;
 
                if (tivt.min_tx_rate == -1 || tivt.max_tx_rate == -1) {
-                       ipaddr_get_vf_rate(tivt.vf, &tmin, &tmax, dev_index);
+                       ipaddr_get_vf_rate(tivt.vf, &tmin, &tmax, dev);
                        if (tivt.min_tx_rate == -1)
                                tivt.min_tx_rate = tmin;
                        if (tivt.max_tx_rate == -1)
@@ -583,7 +587,6 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
        int vf = -1;
        int numtxqueues = -1;
        int numrxqueues = -1;
-       int dev_index = 0;
        int link_netnsid = -1;
        int index = 0;
        int group = -1;
@@ -605,10 +608,8 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
                        if (check_ifname(*argv))
                                invarg("\"name\" not a valid ifname", *argv);
                        name = *argv;
-                       if (!dev) {
+                       if (!dev)
                                dev = name;
-                               dev_index = ll_name_to_index(dev);
-                       }
                } else if (strcmp(*argv, "index") == 0) {
                        NEXT_ARG();
                        if (index)
@@ -660,7 +661,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
                        bool offload = strcmp(*argv, "xdpoffload") == 0;
 
                        NEXT_ARG();
-                       if (xdp_parse(&argc, &argv, req, dev_index,
+                       if (xdp_parse(&argc, &argv, req, dev,
                                      generic, drv, offload))
                                exit(-1);
 
@@ -750,10 +751,10 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
 
                        vflist = addattr_nest(&req->n, sizeof(*req),
                                              IFLA_VFINFO_LIST);
-                       if (dev_index == 0)
+                       if (!dev)
                                missarg("dev");
 
-                       len = iplink_parse_vf(vf, &argc, &argv, req, dev_index);
+                       len = iplink_parse_vf(vf, &argc, &argv, req, dev);
                        if (len < 0)
                                return -1;
                        addattr_nest_end(&req->n, vflist);
@@ -864,10 +865,24 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
                                 IFLA_INET6_ADDR_GEN_MODE, mode);
                        addattr_nest_end(&req->n, afs6);
                        addattr_nest_end(&req->n, afs);
+               } else if (matches(*argv, "link-netns") == 0) {
+                       NEXT_ARG();
+                       if (link_netnsid != -1)
+                               duparg("link-netns/link-netnsid", *argv);
+                       link_netnsid = get_netnsid_from_name(*argv);
+                       /* No nsid? Try to assign one. */
+                       if (link_netnsid < 0)
+                               set_netnsid_from_name(*argv, -1);
+                       link_netnsid = get_netnsid_from_name(*argv);
+                       if (link_netnsid < 0)
+                               invarg("Invalid \"link-netns\" value\n",
+                                      *argv);
+                       addattr32(&req->n, sizeof(*req), IFLA_LINK_NETNSID,
+                                 link_netnsid);
                } else if (matches(*argv, "link-netnsid") == 0) {
                        NEXT_ARG();
                        if (link_netnsid != -1)
-                               duparg("link-netnsid", *argv);
+                               duparg("link-netns/link-netnsid", *argv);
                        if (get_integer(&link_netnsid, *argv, 0))
                                invarg("Invalid \"link-netnsid\" value\n",
                                       *argv);
@@ -916,7 +931,6 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
                        if (check_ifname(*argv))
                                invarg("\"dev\" not a valid ifname", *argv);
                        dev = *argv;
-                       dev_index = ll_name_to_index(dev);
                }
                argc--; argv++;
        }
@@ -931,8 +945,8 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, char **type)
        else if (!strcmp(name, dev))
                name = dev;
 
-       if (dev_index && addr_len) {
-               int halen = nl_get_ll_addr_len(dev_index);
+       if (dev && addr_len) {
+               int halen = nl_get_ll_addr_len(dev);
 
                if (halen >= 0 && halen != addr_len) {
                        fprintf(stderr,
@@ -1127,7 +1141,7 @@ static int do_chflags(const char *dev, __u32 flags, __u32 mask)
        int fd;
        int err;
 
-       strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+       strlcpy(ifr.ifr_name, dev, IFNAMSIZ);
        fd = get_ctl_fd();
        if (fd < 0)
                return -1;
@@ -1154,8 +1168,8 @@ static int do_changename(const char *dev, const char *newdev)
        int fd;
        int err;
 
-       strncpy(ifr.ifr_name, dev, IFNAMSIZ);
-       strncpy(ifr.ifr_newname, newdev, IFNAMSIZ);
+       strlcpy(ifr.ifr_name, dev, IFNAMSIZ);
+       strlcpy(ifr.ifr_newname, newdev, IFNAMSIZ);
        fd = get_ctl_fd();
        if (fd < 0)
                return -1;
@@ -1178,7 +1192,7 @@ static int set_qlen(const char *dev, int qlen)
        if (s < 0)
                return -1;
 
-       strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+       strlcpy(ifr.ifr_name, dev, IFNAMSIZ);
        if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) {
                perror("SIOCSIFXQLEN");
                close(s);
@@ -1198,7 +1212,7 @@ static int set_mtu(const char *dev, int mtu)
        if (s < 0)
                return -1;
 
-       strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+       strlcpy(ifr.ifr_name, dev, IFNAMSIZ);
        if (ioctl(s, SIOCSIFMTU, &ifr) < 0) {
                perror("SIOCSIFMTU");
                close(s);
@@ -1225,7 +1239,7 @@ static int get_address(const char *dev, int *htype)
                return -1;
        }
 
-       strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+       strlcpy(ifr.ifr_name, dev, IFNAMSIZ);
        if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
                perror("SIOCGIFINDEX");
                close(s);
@@ -1256,7 +1270,7 @@ static int parse_address(const char *dev, int hatype, int halen,
        int alen;
 
        memset(ifr, 0, sizeof(*ifr));
-       strncpy(ifr->ifr_name, dev, IFNAMSIZ);
+       strlcpy(ifr->ifr_name, dev, IFNAMSIZ);
        ifr->ifr_hwaddr.sa_family = hatype;
        alen = ll_addr_a2n(ifr->ifr_hwaddr.sa_data, 14, lla);
        if (alen < 0)