blob: a800a36c017d9b290d47ae100f19dd3ab620be77 [file] [log] [blame]
/*
*
* Connection Manager
*
* Copyright (C) 2007-2009 Intel Corporation. All rights reserved.
*
* 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
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <errno.h>
#include <net/if.h>
#ifndef IFF_LOWER_UP
#define IFF_LOWER_UP 0x10000
#endif
#include <glib.h>
#define CONNMAN_API_SUBJECT_TO_CHANGE
#include <connman/plugin.h>
#include <connman/device.h>
#include <connman/inet.h>
#include <connman/rtnl.h>
#include <connman/log.h>
#define _DBG_ETHERNET(fmt, arg...) DBG(DBG_ETHERNET, fmt, ## arg)
struct ethernet_data {
struct connman_rtnl rtnl;
unsigned flags;
unsigned int watch;
};
static void ethernet_newlink(void *user_data, int index, unsigned short type,
const char *ifname, unsigned flags, int change)
{
struct connman_device *device = user_data;
struct ethernet_data *ethernet = connman_device_get_data(device);
_DBG_ETHERNET("ifname %s index %d flags %d change %d", ifname,
index, flags, change);
if ((ethernet->flags & IFF_UP) != (flags & IFF_UP)) {
if (flags & IFF_UP) {
_DBG_ETHERNET("power on");
connman_device_set_powered(device, TRUE);
} else {
_DBG_ETHERNET("power off");
connman_device_set_powered(device, FALSE);
}
}
if ((ethernet->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
if (flags & IFF_LOWER_UP) {
_DBG_ETHERNET("carrier on");
connman_device_set_carrier(device, TRUE);
} else {
_DBG_ETHERNET("carrier off");
connman_device_set_carrier(device, FALSE);
}
}
ethernet->flags = flags;
}
static int ethernet_probe(struct connman_device *device)
{
struct ethernet_data *ethernet;
_DBG_ETHERNET("device %p", device);
ethernet = g_try_new0(struct ethernet_data, 1);
if (ethernet == NULL)
return -ENOMEM;
connman_device_set_data(device, ethernet);
ethernet->flags = 0;
RTNL_INIT(&ethernet->rtnl,
connman_device_get_interface(device), /* name */
CONNMAN_RTNL_PRIORITY_DEFAULT, /* priority */
connman_device_get_index(device), /* device index */
device); /* private */
ethernet->rtnl.newlink = ethernet_newlink;
connman_rtnl_register(&ethernet->rtnl);
return 0;
}
static void ethernet_remove(struct connman_device *device)
{
struct ethernet_data *ethernet = connman_device_get_data(device);
_DBG_ETHERNET("device %p", device);
connman_device_set_data(device, NULL);
connman_rtnl_unregister(&ethernet->rtnl);
g_free(ethernet);
}
static int ethernet_enable(struct connman_device *device)
{
struct ethernet_data *ethernet = connman_device_get_data(device);
_DBG_ETHERNET("device %p", device);
return connman_inet_ifup(ethernet->rtnl.index);
}
static int ethernet_disable(struct connman_device *device)
{
struct ethernet_data *ethernet = connman_device_get_data(device);
_DBG_ETHERNET("device %p", device);
return connman_inet_ifdown(ethernet->rtnl.index);
}
static int ethernet_connect(struct connman_device *device)
{
struct ethernet_data *ethernet = connman_device_get_data(device);
_DBG_ETHERNET("device %p", device);
if (!(ethernet->flags & IFF_LOWER_UP))
return -ENOTCONN;
return connman_device_set_connected(device, TRUE);
}
static int ethernet_disconnect(struct connman_device *device)
{
struct ethernet_data *ethernet = connman_device_get_data(device);
_DBG_ETHERNET("device %p", device);
if (!(ethernet->flags & IFF_LOWER_UP))
return -ENOTCONN;
return connman_device_set_connected(device, FALSE);
}
static struct connman_device_driver ethernet_driver = {
.name = "ethernet",
.type = CONNMAN_DEVICE_TYPE_ETHERNET,
.probe = ethernet_probe,
.remove = ethernet_remove,
.enable = ethernet_enable,
.disable = ethernet_disable,
.connect = ethernet_connect,
.disconnect = ethernet_disconnect,
};
static int ethernet_init(void)
{
return connman_device_driver_register(&ethernet_driver);
}
static void ethernet_exit(void)
{
connman_device_driver_unregister(&ethernet_driver);
}
CONNMAN_PLUGIN_DEFINE(ethernet, "Ethernet interface plugin", VERSION,
CONNMAN_PLUGIN_PRIORITY_DEFAULT, ethernet_init, ethernet_exit)