2 * Copyright (C) 2007 Martin Willi
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include <sys/types.h>
17 #include <libbridge.h>
19 #include <utils/debug.h>
20 #include <collections/linked_list.h>
24 typedef struct private_bridge_t private_bridge_t
;
26 struct private_bridge_t
{
27 /** public interface */
31 /** list of attached interfaces */
32 linked_list_t
*ifaces
;
38 bool iface_control(char *name
, bool up
);
40 METHOD(bridge_t
, get_name
, char*,
41 private_bridge_t
*this)
46 METHOD(bridge_t
, create_iface_enumerator
, enumerator_t
*,
47 private_bridge_t
*this)
49 return this->ifaces
->create_enumerator(this->ifaces
);
52 METHOD(bridge_t
, disconnect_iface
, bool,
53 private_bridge_t
*this, iface_t
*iface
)
55 enumerator_t
*enumerator
;
56 iface_t
*current
= NULL
;
59 enumerator
= this->ifaces
->create_enumerator(this->ifaces
);
60 while (enumerator
->enumerate(enumerator
, (void**)¤t
))
64 if (br_del_interface(this->name
, iface
->get_hostif(iface
)) != 0)
66 DBG1(DBG_LIB
, "removing iface '%s' from bridge '%s' in kernel"
67 " failed: %m", iface
->get_hostif(iface
), this->name
);
71 iface
->set_bridge(iface
, NULL
);
72 this->ifaces
->remove_at(this->ifaces
, enumerator
);
80 DBG1(DBG_LIB
, "iface '%s' not found on bridge '%s'",
81 iface
->get_hostif(iface
), this->name
);
83 enumerator
->destroy(enumerator
);
87 METHOD(bridge_t
, connect_iface
, bool,
88 private_bridge_t
*this, iface_t
*iface
)
90 if (br_add_interface(this->name
, iface
->get_hostif(iface
)) != 0)
92 DBG1(DBG_LIB
, "adding iface '%s' to bridge '%s' failed: %m",
93 iface
->get_hostif(iface
), this->name
);
96 iface
->set_bridge(iface
, &this->public);
97 this->ifaces
->insert_last(this->ifaces
, iface
);
102 * instance counter to (de-)initialize libbridge
104 static int instances
= 0;
106 METHOD(bridge_t
, destroy
, void,
107 private_bridge_t
*this)
109 enumerator_t
*enumerator
;
112 enumerator
= this->ifaces
->create_enumerator(this->ifaces
);
113 while (enumerator
->enumerate(enumerator
, (void**)&iface
))
115 if (br_del_interface(this->name
, iface
->get_hostif(iface
)) != 0)
117 DBG1(DBG_LIB
, "disconnecting iface '%s' failed: %m",
118 iface
->get_hostif(iface
));
120 iface
->set_bridge(iface
, NULL
);
122 enumerator
->destroy(enumerator
);
123 this->ifaces
->destroy(this->ifaces
);
124 iface_control(this->name
, FALSE
);
125 if (br_del_bridge(this->name
) != 0)
127 DBG1(DBG_LIB
, "deleting bridge '%s' from kernel failed: %m",
132 if (--instances
== 0)
139 * create the bridge instance
141 bridge_t
*bridge_create(char *name
)
143 private_bridge_t
*this;
149 DBG1(DBG_LIB
, "libbridge initialization failed: %m");
156 .get_name
= _get_name
,
157 .create_iface_enumerator
= _create_iface_enumerator
,
158 .disconnect_iface
= _disconnect_iface
,
159 .connect_iface
= _connect_iface
,
164 if (br_add_bridge(name
) != 0)
166 DBG1(DBG_LIB
, "creating bridge '%s' failed: %m", name
);
170 if (!iface_control(name
, TRUE
))
172 DBG1(DBG_LIB
, "bringing bridge '%s' up failed: %m", name
);
175 this->name
= strdup(name
);
176 this->ifaces
= linked_list_create();
179 return &this->public;