#include <linux/if_tun.h>
#endif
-/* XXX where do we find if_tun on other platforms? */
+/* Where do we find if_tun on other platforms? */
/* Connection to the kernel through the universal TUN/TAP driver */
}
if (l>0) {
st->buff->size=l;
- st->netlink_to_tunnel(&st->nl,NULL,st->buff);
+ st->netlink_to_tunnel(&st->nl,st->buff);
BUF_ASSERT_FREE(st->buff);
}
}
}
-static void tun_deliver_to_kernel(void *sst, void *cid,
- struct buffer_if *buf)
+static void tun_deliver_to_kernel(void *sst, struct buffer_if *buf)
{
struct tun *st=sst;
BUF_ASSERT_USED(buf);
-
- /* No error checking, because we'd just throw the packet away anyway */
+ /* No error checking, because we'd just throw the packet away
+ anyway if it didn't work. */
write(st->fd,buf->start,buf->size);
BUF_FREE(buf);
}
-static bool_t tun_set_route(void *sst, struct netlink_route *route)
+static bool_t tun_set_route(void *sst, struct netlink_client *routes)
{
struct tun *st=sst;
string_t network, mask, secnetaddr;
-
- if (route->up != route->kup) {
- network=ipaddr_to_string(route->net.prefix);
- mask=ipaddr_to_string(route->net.mask);
- secnetaddr=ipaddr_to_string(st->nl.secnet_address);
- Message(M_INFO,"%s: %s route %s/%d %s kernel routing table\n",
- st->nl.name,route->up?"adding":"deleting",network,
- route->net.len,route->up?"to":"from");
- sys_cmd(st->route_path,"route",route->up?"add":"del","-net",network,
- "netmask",mask,"gw",secnetaddr,(char *)0);
- free(network); free(mask); free(secnetaddr);
- route->kup=route->up;
+ struct subnet_list *nets;
+ uint32_t i;
+
+ if (routes->up != routes->kup) {
+ nets=routes->subnets;
+ for (i=0; i<nets->entries; i++) {
+ network=ipaddr_to_string(nets->list[i].prefix);
+ mask=ipaddr_to_string(nets->list[i].mask);
+ secnetaddr=ipaddr_to_string(st->nl.secnet_address);
+ Message(M_INFO,"%s: %s route %s/%d %s kernel routing table\n",
+ st->nl.name,routes->up?"adding":"deleting",network,
+ nets->list[i].len,routes->up?"to":"from");
+ sys_cmd(st->route_path,"route",routes->up?"add":"del",
+ "-net",network,"netmask",mask,"gw",secnetaddr,(char *)0);
+ free(network); free(mask); free(secnetaddr);
+ }
+ routes->kup=routes->up;
return True;
}
return False;
struct tun *st=sst;
string_t hostaddr,secnetaddr;
uint8_t mtu[6];
- string_t network,mask;
- struct netlink_route *r;
- int i;
+ struct netlink_client *r;
if (st->tun_old) {
if (st->search_for_if) {
snprintf(mtu,6,"%d",st->nl.mtu);
mtu[5]=0;
+ /* XXX on FreeBSD the "-broadcast" and "pointopoint" must be left
+ out. It assumes a point-to-point interface if two IP addresses
+ are specified. */
sys_cmd(st->ifconfig_path,"ifconfig",st->interface_name,
hostaddr,"netmask","255.255.255.255","-broadcast",
"pointopoint",secnetaddr,"mtu",mtu,"up",(char *)0);
- r=st->nl.routes;
- for (i=0; i<st->nl.n_routes; i++) {
- if (r[i].up && !r[i].kup) {
- network=ipaddr_to_string(r[i].net.prefix);
- mask=ipaddr_to_string(r[i].net.mask);
- sys_cmd(st->route_path,"route","add","-net",network,
- "netmask",mask,"gw",secnetaddr,(char *)0);
- r[i].kup=True;
- }
+ for (r=st->nl.clients; r; r=r->next) {
+ tun_set_route(st,r);
}
/* Register for poll() */
if (!st->ifconfig_path) st->ifconfig_path="ifconfig";
if (!st->route_path) st->route_path="route";
st->buff=find_cl_if(dict,"buffer",CL_BUFFER,True,"tun-netlink",loc);
- st->local_address=string_to_ipaddr(
+ st->local_address=string_item_to_ipaddr(
dict_find_item(dict,"local-address", True, "netlink", loc),"netlink");
add_hook(PHASE_GETRESOURCES,tun_phase_hook,st);
st=safe_malloc(sizeof(*st),"tun_old_apply");
- Message(M_WARNING,"the tun-old code has never been tested. Please report "
- "success or failure to steve@greenend.org.uk\n");
-
/* First parameter must be a dict */
item=list_elem(args,0);
if (!item || item->type!=t_dict)
st->netlink_to_tunnel=
netlink_init(&st->nl,st,loc,dict,
- "netlink-tun",NULL,tun_deliver_to_kernel);
+ "netlink-tun",tun_set_route,tun_deliver_to_kernel);
st->tun_old=True;
st->device_path=dict_read_string(dict,"device",False,"tun-netlink",loc);
if (!st->ifconfig_path) st->ifconfig_path="ifconfig";
if (!st->route_path) st->route_path="route";
st->buff=find_cl_if(dict,"buffer",CL_BUFFER,True,"tun-netlink",loc);
- st->local_address=string_to_ipaddr(
+ st->local_address=string_item_to_ipaddr(
dict_find_item(dict,"local-address", True, "netlink", loc),"netlink");
/* Old TUN interface: the network interface name depends on which