system-linux: set master early on apply settings
[project/netifd.git] / system-linux.c
index cc1b5e969132c41ceaa38744faa07b9d94125436..b64c00755606330d1f8acb9df6c68ee9867a4eba 100644 (file)
@@ -203,6 +203,14 @@ abort:
        return;
 }
 
+static void
+nl_udebug_cb(void *priv, struct nl_msg *msg)
+{
+       struct nlmsghdr *nlh = nlmsg_hdr(msg);
+
+       udebug_netlink_msg(priv, nlmsg_get_proto(msg), nlh, nlh->nlmsg_len);
+}
+
 static struct nl_sock *
 create_socket(int protocol, int groups)
 {
@@ -220,6 +228,9 @@ create_socket(int protocol, int groups)
                return NULL;
        }
 
+       nl_socket_set_tx_debug_cb(sock, nl_udebug_cb, &udb_nl);
+       nl_socket_set_rx_debug_cb(sock, nl_udebug_cb, &udb_nl);
+
        return sock;
 }
 
@@ -948,16 +959,19 @@ int system_bridge_addif(struct device *bridge, struct device *dev)
        int tries = 0;
        int ret;
 
-retry:
-       ret = 0;
-       oldbr = system_get_bridge(dev->ifname, dev_buf, sizeof(dev_buf));
-       if (!oldbr || strcmp(oldbr, bridge->ifname) != 0) {
+
+       for (tries = 0; tries < 3; tries++) {
+               ret = 0;
+               oldbr = system_get_bridge(dev->ifname, dev_buf, sizeof(dev_buf));
+               if (oldbr && !strcmp(oldbr, bridge->ifname))
+                       break;
+
                ret = system_bridge_if(bridge->ifname, dev, SIOCBRADDIF, NULL);
-               tries++;
-               D(SYSTEM, "Failed to add device '%s' to bridge '%s' (tries=%d): %s\n",
+               if (!ret)
+                       break;
+
+               D(SYSTEM, "Failed to add device '%s' to bridge '%s' (tries=%d): %s",
                  dev->ifname, bridge->ifname, tries, strerror(errno));
-               if (tries <= 3)
-                       goto retry;
        }
 
        if (dev->wireless)
@@ -1236,9 +1250,9 @@ static int cb_clear_event(struct nl_msg *msg, void *arg)
                return NL_SKIP;
 
        if (type == RTM_DELRULE)
-               D(SYSTEM, "Remove a rule\n");
+               D(SYSTEM, "Remove a rule");
        else
-               D(SYSTEM, "Remove %s from device %s\n",
+               D(SYSTEM, "Remove %s from device %s",
                  type == RTM_DELADDR ? "an address" : "a route",
                  clr->dev->ifname);
 
@@ -1251,9 +1265,9 @@ static int cb_clear_event(struct nl_msg *msg, void *arg)
        ret = nl_send_auto_complete(sock_rtnl, clr->msg);
        if (ret < 0) {
                if (type == RTM_DELRULE)
-                       D(SYSTEM, "Error deleting a rule: %d\n", ret);
+                       D(SYSTEM, "Error deleting a rule: %d", ret);
                else
-                       D(SYSTEM, "Error deleting %s from device '%s': %d\n",
+                       D(SYSTEM, "Error deleting %s from device '%s': %d",
                                type == RTM_DELADDR ? "an address" : "a route",
                                clr->dev->ifname, ret);
        }
@@ -1346,14 +1360,14 @@ void system_if_clear_state(struct device *dev)
        system_if_flags(dev->ifname, 0, IFF_UP);
 
        if (system_is_bridge(dev->ifname)) {
-               D(SYSTEM, "Delete existing bridge named '%s'\n", dev->ifname);
+               D(SYSTEM, "Delete existing bridge named '%s'", dev->ifname);
                system_bridge_delbr(dev);
                return;
        }
 
        bridge = system_get_bridge(dev->ifname, buf, sizeof(buf));
        if (bridge) {
-               D(SYSTEM, "Remove device '%s' from bridge '%s'\n", dev->ifname, bridge);
+               D(SYSTEM, "Remove device '%s' from bridge '%s'", dev->ifname, bridge);
                system_bridge_if(bridge, dev, SIOCBRDELIF, NULL);
        }
 
@@ -1446,7 +1460,7 @@ int system_bridge_addbr(struct device *bridge, struct bridge_config *cfg)
 
        rv = system_rtnl_call(msg);
        if (rv)
-               D(SYSTEM, "Error adding bridge '%s': %d\n", bridge->ifname, rv);
+               D(SYSTEM, "Error adding bridge '%s': %d", bridge->ifname, rv);
 
        return rv;
 
@@ -1502,7 +1516,7 @@ int system_macvlan_add(struct device *macvlan, struct device *dev, struct macvla
 
        rv = system_rtnl_call(msg);
        if (rv)
-               D(SYSTEM, "Error adding macvlan '%s' over '%s': %d\n", macvlan->ifname, dev->ifname, rv);
+               D(SYSTEM, "Error adding macvlan '%s' over '%s': %d", macvlan->ifname, dev->ifname, rv);
 
        return rv;
 
@@ -1590,9 +1604,9 @@ int system_veth_add(struct device *veth, struct veth_config *cfg)
        rv = system_rtnl_call(msg);
        if (rv) {
                if (cfg->flags & VETH_OPT_PEER_NAME)
-                       D(SYSTEM, "Error adding veth '%s' with peer '%s': %d\n", veth->ifname, cfg->peer_name, rv);
+                       D(SYSTEM, "Error adding veth '%s' with peer '%s': %d", veth->ifname, cfg->peer_name, rv);
                else
-                       D(SYSTEM, "Error adding veth '%s': %d\n", veth->ifname, rv);
+                       D(SYSTEM, "Error adding veth '%s': %d", veth->ifname, rv);
        }
 
        return rv;
@@ -1698,7 +1712,7 @@ int system_vlandev_add(struct device *vlandev, struct device *dev, struct vlande
 
        rv = system_rtnl_call(msg);
        if (rv)
-               D(SYSTEM, "Error adding vlandev '%s' over '%s': %d\n", vlandev->ifname, dev->ifname, rv);
+               D(SYSTEM, "Error adding vlandev '%s' over '%s': %d", vlandev->ifname, dev->ifname, rv);
 
        return rv;
 
@@ -2245,6 +2259,15 @@ system_if_apply_settings(struct device *dev, struct device_settings *s, uint64_t
 
        apply_mask &= s->flags;
 
+       if (apply_mask & DEV_OPT_MASTER) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
+               system_set_master(dev, s->master_ifindex);
+               system_refresh_orig_macaddr(dev, &dev->orig_settings);
+#else
+               netifd_log_message(L_WARNING, "%s Your kernel is older than linux 6.1.0, changing DSA port conduit is not supported!", dev->ifname);
+#endif
+       }
+
        memset(&ifr, 0, sizeof(ifr));
        strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name) - 1);
        if (apply_mask & DEV_OPT_MTU) {
@@ -2333,14 +2356,6 @@ system_if_apply_settings(struct device *dev, struct device_settings *s, uint64_t
                system_set_drop_unsolicited_na(dev, s->drop_unsolicited_na ? "1" : "0");
        if (apply_mask & DEV_OPT_ARP_ACCEPT)
                system_set_arp_accept(dev, s->arp_accept ? "1" : "0");
-       if (apply_mask & DEV_OPT_MASTER) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
-               system_set_master(dev, s->master_ifindex);
-               system_refresh_orig_macaddr(dev, &dev->orig_settings);
-#else
-               netifd_log_message(L_WARNING, "%s Your kernel is older than linux 6.1.0, changing DSA port conduit is not supported!", dev->ifname);
-#endif
-       }
        system_set_ethtool_settings(dev, s);
 }
 
@@ -4395,7 +4410,7 @@ static int system_add_vxlan(const char *name, const unsigned int link, struct bl
 
        ret = system_rtnl_call(msg);
        if (ret)
-               D(SYSTEM, "Error adding vxlan '%s': %d\n", name, ret);
+               D(SYSTEM, "Error adding vxlan '%s': %d", name, ret);
 
        return ret;