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>
20 #include <utils/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
);
41 * Implementation of bridge_t.get_name.
43 static char* get_name(private_bridge_t
*this)
49 * Implementation of bridge_t.create_iface_enumerator.
51 static enumerator_t
* create_iface_enumerator(private_bridge_t
*this)
53 return this->ifaces
->create_enumerator(this->ifaces
);
57 * Implementation of bridge_t.disconnect_iface.
59 static bool disconnect_iface(private_bridge_t
*this, iface_t
*iface
)
61 enumerator_t
*enumerator
;
62 iface_t
*current
= NULL
;
65 enumerator
= this->ifaces
->create_enumerator(this->ifaces
);
66 while (enumerator
->enumerate(enumerator
, (void**)¤t
))
70 if (br_del_interface(this->name
, iface
->get_hostif(iface
)) != 0)
72 DBG1("removing iface '%s' from bridge '%s' in kernel failed: %m",
73 iface
->get_hostif(iface
), this->name
);
77 iface
->set_bridge(iface
, NULL
);
78 this->ifaces
->remove_at(this->ifaces
, enumerator
);
86 DBG1("iface '%s' not found on bridge '%s'", iface
->get_hostif(iface
),
89 enumerator
->destroy(enumerator
);
94 * Implementation of bridge_t.connect_iface.
96 static bool connect_iface(private_bridge_t
*this, iface_t
*iface
)
98 if (br_add_interface(this->name
, iface
->get_hostif(iface
)) != 0)
100 DBG1("adding iface '%s' to bridge '%s' failed: %m",
101 iface
->get_hostif(iface
), this->name
);
104 iface
->set_bridge(iface
, &this->public);
105 this->ifaces
->insert_last(this->ifaces
, iface
);
110 * instance counter to (de-)initialize libbridge
112 static int instances
= 0;
115 * Implementation of bridge_t.destroy.
117 static void destroy(private_bridge_t
*this)
119 enumerator_t
*enumerator
;
122 enumerator
= this->ifaces
->create_enumerator(this->ifaces
);
123 while (enumerator
->enumerate(enumerator
, (void**)&iface
))
125 if (br_del_interface(this->name
, iface
->get_hostif(iface
)) != 0)
127 DBG1("disconnecting iface '%s' failed: %m", iface
->get_hostif(iface
));
129 iface
->set_bridge(iface
, NULL
);
131 enumerator
->destroy(enumerator
);
132 this->ifaces
->destroy(this->ifaces
);
133 iface_control(this->name
, FALSE
);
134 if (br_del_bridge(this->name
) != 0)
136 DBG1("deleting bridge '%s' from kernel failed: %m", this->name
);
140 if (--instances
== 0)
147 * create the bridge instance
149 bridge_t
*bridge_create(char *name
)
151 private_bridge_t
*this;
157 DBG1("libbridge initialization failed: %m");
162 this = malloc_thing(private_bridge_t
);
163 this->public.get_name
= (char*(*)(bridge_t
*))get_name
;
164 this->public.create_iface_enumerator
= (enumerator_t
*(*)(bridge_t
*))create_iface_enumerator
;
165 this->public.disconnect_iface
= (bool(*)(bridge_t
*, iface_t
*iface
))disconnect_iface
;
166 this->public.connect_iface
= (bool(*)(bridge_t
*, iface_t
*iface
))connect_iface
;
167 this->public.destroy
= (void*)destroy
;
169 if (br_add_bridge(name
) != 0)
171 DBG1("creating bridge '%s' failed: %m", name
);
175 if (!iface_control(name
, TRUE
))
177 DBG1("bringing bridge '%s' up failed: %m", name
);
180 this->name
= strdup(name
);
181 this->ifaces
= linked_list_create();
184 return &this->public;