netifd: Do not add local/source policy rules multiple times
[project/netifd.git] / system-linux.c
index f51c078..2b17764 100644 (file)
@@ -424,7 +424,7 @@ static int cb_rtnl_event(struct nl_msg *msg, void *arg)
                goto out;
 
        struct device *dev = device_get(nla_data(nla[IFLA_IFNAME]), false);
-       if (!dev || dev->type->keep_link_status)
+       if (!dev)
                goto out;
 
        if (!system_get_dev_sysctl("/sys/class/net/%s/carrier", dev->ifname, buf, sizeof(buf)))
@@ -1053,7 +1053,7 @@ int system_vlandev_del(struct device *vlandev)
        return system_link_del(vlandev->ifname);
 }
 
-static void
+void
 system_if_get_settings(struct device *dev, struct device_settings *s)
 {
        struct ifreq ifr;
@@ -1225,6 +1225,7 @@ int system_if_up(struct device *dev)
 {
        system_if_get_settings(dev, &dev->orig_settings);
        /* Only keep orig settings based on what needs to be set */
+       dev->orig_settings.valid_flags = dev->orig_settings.flags;
        dev->orig_settings.flags &= dev->settings.flags;
        system_if_apply_settings(dev, &dev->settings, dev->settings.flags);
        return system_if_flags(dev->ifname, IFF_UP, 0);
@@ -1295,10 +1296,13 @@ int system_if_check(struct device *dev)
        int ret = 1;
 
        msg = nlmsg_alloc_simple(RTM_GETLINK, 0);
-       if (!msg || nlmsg_append(msg, &ifi, sizeof(ifi), 0) ||
-           nla_put_string(msg, IFLA_IFNAME, dev->ifname))
+       if (!msg)
                goto out;
 
+       if (nlmsg_append(msg, &ifi, sizeof(ifi), 0) ||
+           nla_put_string(msg, IFLA_IFNAME, dev->ifname))
+               goto free;
+
        nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_if_check_valid, &chk);
        nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, cb_if_check_ack, &chk);
        nl_cb_err(cb, NL_CB_CUSTOM, cb_if_check_error, &chk);
@@ -1307,9 +1311,10 @@ int system_if_check(struct device *dev)
        while (chk.pending > 0)
                nl_recvmsgs(sock_rtnl, cb);
 
-       nlmsg_free(msg);
        ret = chk.pending;
 
+free:
+       nlmsg_free(msg);
 out:
        nl_cb_put(cb);
        return ret;
@@ -1532,8 +1537,10 @@ static int system_addr(struct device *dev, struct device_addr *addr, int cmd)
 
                if (addr->valid_until) {
                        int64_t valid = addr->valid_until - now;
-                       if (valid <= 0)
+                       if (valid <= 0) {
+                               nlmsg_free(msg);
                                return -1;
+                       }
                        else if (valid > UINT32_MAX)
                                valid = UINT32_MAX;
 
@@ -1785,10 +1792,8 @@ static int system_iprule(struct iprule *rule, int cmd)
                .rtm_flags = 0,
        };
 
-       if (cmd == RTM_NEWRULE) {
+       if (cmd == RTM_NEWRULE)
                rtm.rtm_type = RTN_UNICAST;
-               rtm.rtm_flags |= NLM_F_REPLACE | NLM_F_EXCL;
-       }
 
        if (rule->invert)
                rtm.rtm_flags |= FIB_RULE_INVERT;