[connman] Added Tizen Wi-Fi Mesh
[platform/upstream/connman.git] / src / session.c
index 00ef369..26cbf87 100644 (file)
@@ -3,7 +3,7 @@
  *  Connection Manager
  *
  *  Copyright (C) 2007-2014  Intel Corporation. All rights reserved.
- *  Copyright (C) 2011-2014  BWM CarIT GmbH. All rights reserved.
+ *  Copyright (C) 2011-2014  BMW Car IT GmbH.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
@@ -37,13 +37,6 @@ static GHashTable *session_hash;
 static GHashTable *service_hash;
 static struct connman_session *ecall_session;
 static uint32_t session_mark = 256;
-static struct firewall_context *global_firewall = NULL;
-
-enum connman_session_state {
-       CONNMAN_SESSION_STATE_DISCONNECTED   = 0,
-       CONNMAN_SESSION_STATE_CONNECTED      = 1,
-       CONNMAN_SESSION_STATE_ONLINE         = 2,
-};
 
 struct session_info {
        struct connman_session_config config;
@@ -64,6 +57,7 @@ struct connman_session {
        struct connman_service *service_last;
        struct connman_session_config *policy_config;
        GSList *user_allowed_bearers;
+       char *user_allowed_interface;
 
        bool ecall;
 
@@ -73,6 +67,7 @@ struct connman_session {
        int index;
        char *gateway;
        bool policy_routing;
+       bool snat_enabled;
 };
 
 struct connman_service_info {
@@ -80,6 +75,15 @@ struct connman_service_info {
        GSList *sessions;
 };
 
+struct fw_snat {
+       GSList *sessions;
+       int id;
+       int index;
+       struct firewall_context *fw;
+};
+
+GSList *fw_snat_list;
+
 static struct connman_session_policy *policy;
 static void session_activate(struct connman_session *session);
 static void session_deactivate(struct connman_session *session);
@@ -190,108 +194,118 @@ static char *service2bearer(enum connman_service_type type)
        case CONNMAN_SERVICE_TYPE_GPS:
        case CONNMAN_SERVICE_TYPE_P2P:
        case CONNMAN_SERVICE_TYPE_UNKNOWN:
+#if defined TIZEN_EXT_WIFI_MESH
+       case CONNMAN_SERVICE_TYPE_MESH:
+#endif
                return "";
        }
 
        return "";
 }
 
-static int init_firewall(void)
+static struct fw_snat *fw_snat_lookup(int index)
 {
-       struct firewall_context *fw;
-       int err;
+       struct fw_snat *fw_snat;
+       GSList *list;
 
-       if (global_firewall)
-               return 0;
+       for (list = fw_snat_list; list; list = list->next) {
+               fw_snat = list->data;
 
-       fw = __connman_firewall_create();
+               if (fw_snat->index == index)
+                       return fw_snat;
+       }
+       return NULL;
+}
 
-       err = __connman_firewall_add_rule(fw, "mangle", "INPUT",
-                                       "-j CONNMARK --restore-mark");
-       if (err < 0)
-               goto err;
+static int fw_snat_create(struct connman_session *session,
+                               int index, const char *ifname, const char *addr)
+{
+       struct fw_snat *fw_snat;
+       int err;
 
-       err = __connman_firewall_add_rule(fw, "mangle", "POSTROUTING",
-                                       "-j CONNMARK --save-mark");
-       if (err < 0)
-               goto err;
+       fw_snat = g_new0(struct fw_snat, 1);
 
-       err = __connman_firewall_enable(fw);
-       if (err < 0)
+       fw_snat->fw = __connman_firewall_create();
+       fw_snat->index = index;
+
+       fw_snat->id = __connman_firewall_enable_snat(fw_snat->fw,
+                                               index, ifname, addr);
+       if (fw_snat->id < 0) {
+               err = fw_snat->id;
                goto err;
+       }
 
-       global_firewall = fw;
+       fw_snat_list = g_slist_prepend(fw_snat_list, fw_snat);
+       fw_snat->sessions = g_slist_prepend(fw_snat->sessions, session);
 
        return 0;
-
 err:
-       __connman_firewall_destroy(fw);
-
+       __connman_firewall_destroy(fw_snat->fw);
+       g_free(fw_snat);
        return err;
 }
 
-static void cleanup_firewall(void)
+static void fw_snat_ref(struct connman_session *session,
+                               struct fw_snat *fw_snat)
 {
-       if (!global_firewall)
+       if (g_slist_find(fw_snat->sessions, session))
                return;
+       fw_snat->sessions = g_slist_prepend(fw_snat->sessions, session);
+}
 
-       __connman_firewall_disable(global_firewall);
-       __connman_firewall_destroy(global_firewall);
+static void fw_snat_unref(struct connman_session *session,
+                               struct fw_snat *fw_snat)
+{
+       fw_snat->sessions = g_slist_remove(fw_snat->sessions, session);
+       if (fw_snat->sessions)
+               return;
+
+       fw_snat_list = g_slist_remove(fw_snat_list, fw_snat);
+
+       __connman_firewall_disable_snat(fw_snat->fw);
+       __connman_firewall_destroy(fw_snat->fw);
+       g_free(fw_snat);
 }
 
 static int init_firewall_session(struct connman_session *session)
 {
        struct firewall_context *fw;
        int err;
+       struct connman_ipconfig *ipconfig = NULL;
+       const char *addr = NULL;
 
-       if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN)
+       if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN &&
+                       !session->info->config.source_ip_rule)
                return 0;
 
        DBG("");
 
-       err = init_firewall();
-       if (err < 0)
-               return err;
+       if (session->info->config.source_ip_rule) {
+               ipconfig = __connman_service_get_ip4config(session->service);
+               if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN && !ipconfig)
+                       return 0;
+       }
 
        fw = __connman_firewall_create();
        if (!fw)
                return -ENOMEM;
 
-       switch (session->policy_config->id_type) {
-       case CONNMAN_SESSION_ID_TYPE_UID:
-               err = __connman_firewall_add_rule(fw, "mangle", "OUTPUT",
-                               "-m owner --uid-owner %s -j MARK --set-mark %d",
-                                               session->policy_config->id,
-                                               session->mark);
-               break;
-       case CONNMAN_SESSION_ID_TYPE_GID:
-               err = __connman_firewall_add_rule(fw, "mangle", "OUTPUT",
-                               "-m owner --gid-owner %s -j MARK --set-mark %d",
-                                               session->policy_config->id,
-                                               session->mark);
-               break;
-       case CONNMAN_SESSION_ID_TYPE_LSM:
-       default:
-               err = -EINVAL;
+       if (session->info->config.source_ip_rule && ipconfig) {
+               addr = __connman_ipconfig_get_local(ipconfig);
        }
 
-       if (err < 0)
-               goto err;
-
+       err =__connman_firewall_enable_marking(fw,
+                                       session->policy_config->id_type,
+                                       session->policy_config->id,
+                                       addr, session->mark);
+       if (err < 0) {
+               __connman_firewall_destroy(fw);
+               return err;
+       }
        session->id_type = session->policy_config->id_type;
-
-       err = __connman_firewall_enable(fw);
-       if (err)
-               goto err;
-
        session->fw = fw;
 
        return 0;
-
-err:
-       __connman_firewall_destroy(fw);
-
-       return err;
 }
 
 static void cleanup_firewall_session(struct connman_session *session)
@@ -299,7 +313,8 @@ static void cleanup_firewall_session(struct connman_session *session)
        if (!session->fw)
                return;
 
-       __connman_firewall_disable(session->fw);
+       __connman_firewall_disable_marking(session->fw);
+       __connman_firewall_disable_snat(session->fw);
        __connman_firewall_destroy(session->fw);
 
        session->fw = NULL;
@@ -309,7 +324,11 @@ static int init_routing_table(struct connman_session *session)
 {
        int err;
 
-       if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN)
+       if (session->policy_config->id_type == CONNMAN_SESSION_ID_TYPE_UNKNOWN &&
+                       !session->info->config.source_ip_rule)
+               return 0;
+
+       if (!session->service)
                return 0;
 
        DBG("");
@@ -348,6 +367,7 @@ static void add_default_route(struct connman_session *session)
 {
        struct connman_ipconfig *ipconfig;
        int err;
+       struct in_addr addr = { INADDR_ANY };
 
        if (!session->service)
                return;
@@ -356,6 +376,9 @@ static void add_default_route(struct connman_session *session)
        session->index = __connman_ipconfig_get_index(ipconfig);
        session->gateway = g_strdup(__connman_ipconfig_get_gateway(ipconfig));
 
+       if (!session->gateway)
+               session->gateway = g_strdup(inet_ntoa(addr));
+
        DBG("index %d routing table %d default gateway %s",
                session->index, session->mark, session->gateway);
 
@@ -365,6 +388,62 @@ static void add_default_route(struct connman_session *session)
                DBG("session %p %s", session, strerror(-err));
 }
 
+static void del_nat_rules(struct connman_session *session)
+{
+       struct fw_snat *fw_snat;
+
+       if (!session->snat_enabled)
+               return;
+
+       session->snat_enabled = false;
+       fw_snat = fw_snat_lookup(session->index);
+
+       if (!fw_snat)
+               return;
+
+       fw_snat_unref(session, fw_snat);
+}
+
+static void add_nat_rules(struct connman_session *session)
+{
+       struct connman_ipconfig *ipconfig;
+       struct fw_snat *fw_snat;
+       const char *addr;
+       int index, err;
+       char *ifname;
+
+       if (!session->service)
+               return;
+
+       ipconfig = __connman_service_get_ip4config(session->service);
+       index = __connman_ipconfig_get_index(ipconfig);
+       ifname = connman_inet_ifname(index);
+       addr = __connman_ipconfig_get_local(ipconfig);
+
+       if (!addr)
+               return;
+
+       session->snat_enabled = true;
+       fw_snat = fw_snat_lookup(index);
+       if (fw_snat) {
+               fw_snat_ref(session, fw_snat);
+               return;
+       }
+
+       err = fw_snat_create(session, index, ifname, addr);
+       if (err < 0) {
+               DBG("failed to add SNAT rule");
+               session->snat_enabled = false;
+       }
+
+       g_free(ifname);
+}
+
+uint32_t connman_session_firewall_get_fwmark(struct connman_session *session)
+{
+       return session->mark;
+}
+
 static void cleanup_routing_table(struct connman_session *session)
 {
        DBG("");
@@ -381,12 +460,24 @@ static void cleanup_routing_table(struct connman_session *session)
        del_default_route(session);
 }
 
+static void update_firewall(struct connman_session *session)
+{
+       cleanup_firewall_session(session);
+       init_firewall_session(session);
+}
+
 static void update_routing_table(struct connman_session *session)
 {
-       del_default_route(session);
+       cleanup_routing_table(session);
+       init_routing_table(session);
        add_default_route(session);
 }
 
+static void cleanup_nat_rules(struct connman_session *session)
+{
+       del_nat_rules(session);
+}
+
 static void destroy_policy_config(struct connman_session *session)
 {
        if (!policy) {
@@ -407,6 +498,7 @@ static void free_session(struct connman_session *session)
 
        destroy_policy_config(session);
        g_slist_free(session->info->config.allowed_bearers);
+       g_free(session->info->config.allowed_interface);
        g_free(session->owner);
        g_free(session->session_path);
        g_free(session->notify_path);
@@ -434,6 +526,7 @@ static void cleanup_session(gpointer user_data)
 
        DBG("remove %s", session->session_path);
 
+       cleanup_nat_rules(session);
        cleanup_routing_table(session);
        cleanup_firewall_session(session);
 
@@ -444,6 +537,7 @@ static void cleanup_session(gpointer user_data)
        update_session_state(session);
 
        g_slist_free(session->user_allowed_bearers);
+       g_free(session->user_allowed_interface);
 
        free_session(session);
 }
@@ -455,6 +549,8 @@ struct creation_data {
        /* user config */
        enum connman_session_type type;
        GSList *allowed_bearers;
+       char *allowed_interface;
+       bool source_ip_rule;
 };
 
 static void cleanup_creation_data(struct creation_data *creation_data)
@@ -466,6 +562,7 @@ static void cleanup_creation_data(struct creation_data *creation_data)
                dbus_message_unref(creation_data->pending);
 
        g_slist_free(creation_data->allowed_bearers);
+       g_free(creation_data->allowed_interface);
        g_free(creation_data);
 }
 
@@ -543,6 +640,7 @@ void connman_session_set_default_config(struct connman_session_config *config)
        config->ecall = FALSE;
 
        g_slist_free(config->allowed_bearers);
+       config->allowed_bearers = NULL;
        add_default_bearer_types(&config->allowed_bearers);
 }
 
@@ -628,18 +726,18 @@ static int parse_bearers(DBusMessageIter *iter, GSList **list)
        return 0;
 }
 
-static void filter_bearer(GSList *policy_bearers,
-                               enum connman_service_type bearer,
+static void filter_bearer(GSList *bearers,
+                               enum connman_service_type policy,
                                GSList **list)
 {
-       enum connman_service_type policy;
+       enum connman_service_type bearer;
        GSList *it;
 
-       if (!policy_bearers)
+       if (!bearers)
                return;
 
-       for (it = policy_bearers; it; it = it->next) {
-               policy = GPOINTER_TO_INT(it->data);
+       for (it = bearers; it; it = it->next) {
+               bearer = GPOINTER_TO_INT(it->data);
 
                if (policy != bearer)
                        continue;
@@ -652,18 +750,29 @@ static void filter_bearer(GSList *policy_bearers,
 static void apply_policy_on_bearers(GSList *policy_bearers, GSList *bearers,
                                GSList **list)
 {
-       enum connman_service_type bearer;
+       enum connman_service_type policy_bearer;
        GSList *it;
 
        *list = NULL;
 
-       for (it = bearers; it; it = it->next) {
-               bearer = GPOINTER_TO_INT(it->data);
+       for (it = policy_bearers; it; it = it->next) {
+               policy_bearer = GPOINTER_TO_INT(it->data);
 
-               filter_bearer(policy_bearers, bearer, list);
+               filter_bearer(bearers, policy_bearer, list);
        }
 }
 
+static char * apply_policy_on_interface(const char *policy_interface,
+                               const char *user_interface)
+{
+       if (policy_interface)
+               return g_strdup(policy_interface);
+       else if (user_interface)
+               return g_strdup(user_interface);
+       else
+               return NULL;
+}
+
 const char *connman_session_get_owner(struct connman_session *session)
 {
        return session->owner;
@@ -809,6 +918,28 @@ static void append_notify(DBusMessageIter *dict,
                info_last->config.allowed_bearers = info->config.allowed_bearers;
        }
 
+       if (session->append_all ||
+                       info->config.allowed_interface != info_last->config.allowed_interface) {
+               char *ifname = info->config.allowed_interface;
+               if (!ifname)
+                       ifname = "*";
+               connman_dbus_dict_append_basic(dict, "AllowedInterface",
+                                               DBUS_TYPE_STRING,
+                                               &ifname);
+               info_last->config.allowed_interface = info->config.allowed_interface;
+       }
+
+       if (session->append_all ||
+                       info->config.source_ip_rule != info_last->config.source_ip_rule) {
+               dbus_bool_t source_ip_rule = FALSE;
+               if (info->config.source_ip_rule)
+                       source_ip_rule = TRUE;
+               connman_dbus_dict_append_basic(dict, "SourceIPRule",
+                                               DBUS_TYPE_BOOLEAN,
+                                               &source_ip_rule);
+               info_last->config.source_ip_rule = info->config.source_ip_rule;
+       }
+
        session->append_all = false;
 }
 
@@ -828,7 +959,9 @@ static bool compute_notifiable_changes(struct connman_session *session)
                return true;
 
        if (info->config.allowed_bearers != info_last->config.allowed_bearers ||
-                       info->config.type != info_last->config.type)
+                       info->config.type != info_last->config.type ||
+                       info->config.allowed_interface != info_last->config.allowed_interface ||
+                       info->config.source_ip_rule != info_last->config.source_ip_rule)
                return true;
 
        return false;
@@ -882,6 +1015,7 @@ int connman_session_config_update(struct connman_session *session)
 {
        struct session_info *info = session->info;
        GSList *allowed_bearers;
+       char *allowed_interface;
        int err;
 
        DBG("session %p", session);
@@ -907,6 +1041,10 @@ int connman_session_config_update(struct connman_session *session)
                session->user_allowed_bearers,
                &allowed_bearers);
 
+       allowed_interface = apply_policy_on_interface(
+               session->policy_config->allowed_interface,
+               session->user_allowed_interface);
+
        if (session->active)
                set_active_session(session, false);
 
@@ -916,6 +1054,9 @@ int connman_session_config_update(struct connman_session *session)
        g_slist_free(info->config.allowed_bearers);
        info->config.allowed_bearers = allowed_bearers;
 
+       g_free(info->config.allowed_interface);
+       info->config.allowed_interface = allowed_interface;
+
        session_activate(session);
 
        info->config.type = apply_policy_on_type(
@@ -1024,6 +1165,7 @@ static DBusMessage *change_session(DBusConnection *conn,
 
                        session->active = false;
                        session_deactivate(session);
+                       update_session_state(session);
 
                        g_slist_free(info->config.allowed_bearers);
                        session->user_allowed_bearers = allowed_bearers;
@@ -1044,6 +1186,38 @@ static DBusMessage *change_session(DBusConnection *conn,
                        info->config.type = apply_policy_on_type(
                                session->policy_config->type,
                                connman_session_parse_connection_type(val));
+               } else if (g_str_equal(name, "AllowedInterface")) {
+                       dbus_message_iter_get_basic(&value, &val);
+                       if (session->active)
+                               set_active_session(session, false);
+
+                       session->active = false;
+                       session_deactivate(session);
+                       update_session_state(session);
+
+                       g_free(session->user_allowed_interface);
+                       /* empty string means allow any interface */
+                       if (!g_strcmp0(val, ""))
+                               session->user_allowed_interface = NULL;
+                       else
+                               session->user_allowed_interface = g_strdup(val);
+
+                       info->config.allowed_interface = apply_policy_on_interface(
+                               session->policy_config->allowed_interface,
+                               session->user_allowed_interface);
+
+                       session_activate(session);
+               } else {
+                       goto err;
+               }
+               break;
+       case DBUS_TYPE_BOOLEAN:
+               if (g_str_equal(name, "SourceIPRule")) {
+                       dbus_bool_t source_ip_rule;
+                       dbus_message_iter_get_basic(&value, &source_ip_rule);
+
+                       info->config.source_ip_rule = source_ip_rule;
+                       update_session_state(session);
                } else {
                        goto err;
                }
@@ -1149,6 +1323,7 @@ static int session_policy_config_cb(struct connman_session *session,
                goto err;
 
        session->policy_config = config;
+       session->info->config.source_ip_rule = creation_data->source_ip_rule;
 
        session->mark = session_mark++;
        session->index = -1;
@@ -1177,11 +1352,18 @@ static int session_policy_config_cb(struct connman_session *session,
        session->user_allowed_bearers = creation_data->allowed_bearers;
        creation_data->allowed_bearers = NULL;
 
+       session->user_allowed_interface = creation_data->allowed_interface;
+       creation_data->allowed_interface = NULL;
+
        apply_policy_on_bearers(
                        session->policy_config->allowed_bearers,
                        session->user_allowed_bearers,
                        &info->config.allowed_bearers);
 
+       info->config.allowed_interface = apply_policy_on_interface(
+               session->policy_config->allowed_interface,
+               session->user_allowed_interface);
+
        g_hash_table_replace(session_hash, session->session_path, session);
 
        DBG("add %s", session->session_path);
@@ -1206,6 +1388,8 @@ static int session_policy_config_cb(struct connman_session *session,
        info_last->config.priority = info->config.priority;
        info_last->config.roaming_policy = info->config.roaming_policy;
        info_last->config.allowed_bearers = info->config.allowed_bearers;
+       info_last->config.allowed_interface = info->config.allowed_interface;
+       info_last->config.source_ip_rule = info->config.source_ip_rule;
 
        session->append_all = true;
 
@@ -1293,11 +1477,29 @@ int __connman_session_create(DBusMessage *msg)
                                        connman_session_parse_connection_type(val);
 
                                user_connection_type = true;
+                       } else if (g_str_equal(key, "AllowedInterface")) {
+                               dbus_message_iter_get_basic(&value, &val);
+                               creation_data->allowed_interface = g_strdup(val);
                        } else {
                                err = -EINVAL;
                                goto err;
                        }
+                       break;
+               case DBUS_TYPE_BOOLEAN:
+                       if (g_str_equal(key, "SourceIPRule")) {
+                               dbus_bool_t source_ip_rule;
+                               dbus_message_iter_get_basic(&value, &source_ip_rule);
+                               creation_data->source_ip_rule = source_ip_rule;
+                       } else {
+                               err = -EINVAL;
+                               goto err;
+                       }
+                       break;
+               default:
+                       err = -EINVAL;
+                       goto err;
                }
+
                dbus_message_iter_next(&array);
        }
 
@@ -1481,7 +1683,14 @@ static void update_session_state(struct connman_session *session)
 
        DBG("session %p state %s", session, state2string(state));
 
+       update_firewall(session);
+       del_nat_rules(session);
        update_routing_table(session);
+       add_nat_rules(session);
+
+       if (policy && policy->update_session_state)
+               policy->update_session_state(session, state);
+
        session_notify(session);
 }
 
@@ -1490,17 +1699,31 @@ static bool session_match_service(struct connman_session *session,
 {
        enum connman_service_type bearer_type;
        enum connman_service_type service_type;
+       enum connman_service_type current_service_type;
        GSList *list;
+       char *ifname;
 
        if (policy && policy->allowed)
                return policy->allowed(session, service);
 
+       current_service_type = connman_service_get_type(session->service);
+
        for (list = session->info->config.allowed_bearers; list; list = list->next) {
                bearer_type = GPOINTER_TO_INT(list->data);
                service_type = connman_service_get_type(service);
+               ifname = connman_service_get_interface(service);
 
-               if (bearer_type == service_type)
-                       return true;
+               if (bearer_type == current_service_type)
+                       return false;
+
+               if (bearer_type == service_type &&
+                       (session->info->config.allowed_interface == NULL ||
+                       !g_strcmp0(session->info->config.allowed_interface, "*") ||
+                       !g_strcmp0(session->info->config.allowed_interface, ifname))) {
+                               g_free(ifname);
+                               return true;
+               }
+               g_free(ifname);
        }
 
        return false;
@@ -1521,6 +1744,7 @@ static bool is_session_connected(struct connman_session *session,
        case CONNMAN_SERVICE_STATE_READY:
                if (session->info->config.type == CONNMAN_SESSION_TYPE_INTERNET)
                        return false;
+               /* fall through */
        case CONNMAN_SERVICE_STATE_ONLINE:
                return true;
        }
@@ -1536,6 +1760,40 @@ static void session_activate(struct connman_session *session)
        if (!service_hash)
                return;
 
+       if (policy && policy->get_service_for_session) {
+               struct connman_service *service;
+               struct connman_service_info *info;
+               GSList *service_list = NULL;
+               enum connman_service_state state = CONNMAN_SESSION_STATE_DISCONNECTED;
+
+               g_hash_table_iter_init(&iter, service_hash);
+
+               while (g_hash_table_iter_next(&iter, &key, &value)) {
+                       struct connman_service_info *info = value;
+                       state = __connman_service_get_state(info->service);
+
+                       if (is_session_connected(session, state))
+                               service_list = g_slist_prepend(service_list,
+                                                              info->service);
+               }
+
+               service_list = g_slist_reverse(service_list);
+               service = policy->get_service_for_session(session, service_list);
+
+               if (service) {
+                       info = g_hash_table_lookup(service_hash, service);
+                       DBG("session %p add service %p", session, info->service);
+
+                       info->sessions = g_slist_prepend(info->sessions,
+                                                       session);
+                       session->service = info->service;
+                       update_session_state(session);
+               }
+
+               g_slist_free(service_list);
+               return;
+       }
+
        g_hash_table_iter_init(&iter, service_hash);
        while (g_hash_table_iter_next(&iter, &key, &value)) {
                struct connman_service_info *info = value;
@@ -1630,10 +1888,10 @@ static void handle_service_state_offline(struct connman_service *service,
 
                session->service = NULL;
                update_session_state(session);
+               session_activate(session);
        }
 }
 
-
 static void service_state_changed(struct connman_service *service,
                                enum connman_service_state state)
 {
@@ -1693,7 +1951,7 @@ static void ipconfig_changed(struct connman_service *service,
                        continue;
 
                if (session->service && session->service == service) {
-                       update_routing_table(session);
+                       update_session_state(session);
 
                        if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
                                ipconfig_ipv4_changed(session);
@@ -1730,12 +1988,6 @@ int __connman_session_init(void)
 
        service_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
                                                NULL, cleanup_service);
-       if (__connman_firewall_is_up()) {
-               err = init_firewall();
-               if (err < 0)
-                       return err;
-       }
-
        return 0;
 }
 
@@ -1746,8 +1998,6 @@ void __connman_session_cleanup(void)
        if (!connection)
                return;
 
-       cleanup_firewall();
-
        connman_notifier_unregister(&session_notifier);
 
        g_hash_table_foreach(session_hash, release_session, NULL);