00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifdef HAVE_CONFIG_H
00014 #include "config.h"
00015 #endif
00016
00017 #include <sys/socket.h>
00018 #include <netinet/in.h>
00019 #include <arpa/inet.h>
00020 #include <time.h>
00021
00022 #include "mn.h"
00023 #include "mn_tunnel.h"
00024 #include "debug.h"
00025 #include "util.h"
00026
00027 extern struct mn_data mn;
00028 extern struct mn_config config;
00029
00030 int real_tunnel_up;
00031
00032
00033
00034
00035 static char tunnel_device[IFNAMSIZ];
00036 static struct in_addr old_tunnel_addr;
00037
00038 static char old_tunnel_device[IFNAMSIZ];
00039 static time_t old_tunnel_expire;
00040
00041 static int tunnel_b_up;
00042
00043
00044 static char*
00045 return_home_net_route(void)
00046 {
00047 int i;
00048 char *dev = NULL, *adv_dev = NULL;
00049
00050 if (config.home_net_addr_plen < 0) {
00051 DEBUG(DEBUG_MESSAGES, "return_home_net_route:"
00052 " config.home_net_addr_plen < 0\n");
00053 return NULL;
00054 }
00055
00056
00057 if (mn.current_adv != NULL) {
00058 for (i = 0; i < MAX_INTERFACES; i++) {
00059 if (mn.iface[i].s > -1 &&
00060 strcmp(mn.current_adv->ifname, mn.iface[i].device)
00061 == 0) {
00062 DEBUG(DEBUG_MESSAGES, "return_home_net_route:"
00063 " found current adv interface\n");
00064 adv_dev = mn.current_adv->ifname;
00065 break;
00066 }
00067 }
00068 }
00069
00070
00071
00072 if (adv_dev != NULL &&
00073 ntohs(mn.current_adv->adv.ext->opts) & AGENT_ADV_HOME_AGENT &&
00074 config.ha_ip_addr.s_addr == mn.current_adv->addr.s_addr) {
00075 DEBUG(DEBUG_MESSAGES, "return_home_net_route: "
00076 "found interface where the HA is\n");
00077 dev = adv_dev;
00078 }
00079
00080
00081 if (dev == NULL && mn.start_default_device[0] != '\0') {
00082 for (i = 0; i < MAX_INTERFACES; i++) {
00083 if (mn.iface[i].s > -1 &&
00084 strcmp(mn.start_default_device, mn.iface[i].device)
00085 == 0) {
00086 dev = mn.start_default_device;
00087 break;
00088 }
00089 }
00090 }
00091
00092
00093 if (dev == NULL && adv_dev != NULL)
00094 dev = adv_dev;
00095
00096 if (dev == NULL) {
00097
00098 for (i = 0; i < MAX_INTERFACES; i++) {
00099 if (mn.iface[i].s > -1) {
00100 dev = mn.iface[i].device;
00101 break;
00102 }
00103 }
00104 }
00105
00106 if (dev == NULL) {
00107 DEBUG(DEBUG_INFO,
00108 "No active device found - home net route not added\n");
00109 return NULL;
00110 }
00111
00112 mn.cur_route_info.known = 1;
00113 mn.cur_route_info.via.s_addr = config.home_net_gateway.s_addr;
00114 memcpy(mn.cur_route_info.ifname, dev, IFNAMSIZ);
00115 mn.cur_route_info.ifindex = dyn_ip_get_ifindex(dev);
00116 memcpy(mn.cur_route_info.ifname, dev, IFNAMSIZ);
00117 mn.cur_route_info.ifindex_net = mn.cur_route_info.ifindex;
00118
00119 #ifdef DYN_TARGET_WINDOWS
00120 if (mn.home_net_route_set_via_fa) {
00121 int count;
00122
00123 DEBUG(DEBUG_INFO, "Trying to delete home net route via FA\n");
00124 count = dyn_ip_route_delete_net_routes(
00125 &config.home_net_addr,
00126 config.home_net_addr_plen);
00127 if (count < 0) {
00128 DEBUG(DEBUG_INFO, " failed to delete home net route "
00129 "via FA\n");
00130 } else {
00131 DEBUG(DEBUG_INFO, " home net route delete count: "
00132 "%i\n", count);
00133 mn.home_net_route_set_via_fa = 0;
00134 }
00135 }
00136 #endif
00137
00138 DEBUG(DEBUG_INFO, "Returning home net route %s/%i to %s\n",
00139 inet_ntoa(config.home_net_addr), config.home_net_addr_plen, dev);
00140 if (dyn_ip_route_add_net(dev, &config.home_net_addr,
00141 config.home_net_addr_plen) != 0) {
00142 LOG2(LOG_ERR,
00143 "Home net route (%s/%i => %s) add failed\n",
00144 inet_ntoa(config.home_net_addr),
00145 config.home_net_addr_plen, dev);
00146 }
00147 return dev;
00148 }
00149
00150 void
00151 check_old_tunnel_expiration(void)
00152 {
00153 #ifdef MN_ENABLE_TUNNELING
00154 if (old_tunnel_expire == 0 ||
00155 time(NULL) <= old_tunnel_expire)
00156 return;
00157
00158 old_tunnel_expire = 0;
00159 if (dyn_ip_tunnel_del(old_tunnel_device) != 0) {
00160 LOG2(LOG_ERR, "tunnel delete failed for old tunnel\n");
00161 return;
00162 }
00163 #endif
00164 }
00165
00166 void
00167 init_tunneling(void)
00168 {
00169 DEBUG(DEBUG_INFO, "Init tunneling\n");
00170
00171 dynamics_strlcpy(tunnel_device, TUNNEL_DEVICE, sizeof(tunnel_device));
00172 real_tunnel_up = 0;
00173 tunnel_b_up = 0;
00174 }
00175
00176
00177 void
00178 close_tunneling(void)
00179 {
00180 DEBUG(DEBUG_INFO, "Close tunneling\n");
00181
00182 if (real_tunnel_up) stop_tunneling();
00183
00184 reply_waiting_api(API_FAILED, NULL, 0);
00185 }
00186
00196 static int
00197 make_tunnel(struct in_addr local_addr, struct in_addr ma_addr)
00198 {
00199 struct in_addr any;
00200
00201 if (old_tunnel_expire != 0) {
00202
00203
00204 old_tunnel_expire = 0;
00205
00206 if (old_tunnel_addr.s_addr == ma_addr.s_addr) {
00207 DEBUG(DEBUG_INFO, "make_tunnel - reusing old (lazy "
00208 "deleted) tunnel\n");
00209 return 0;
00210 }
00211
00212
00213
00214 if (dyn_ip_tunnel_del(old_tunnel_device) != 0) {
00215 LOG2(LOG_ERR, "tunnel delete failed for old tunnel\n");
00216 }
00217 }
00218
00219 any.s_addr = 0;
00220 DEBUG(DEBUG_INFO, "Adding tunnel %s => %s\n", tunnel_device,
00221 inet_ntoa(ma_addr));
00222 if (dyn_ip_tunnel_add(tunnel_device, ma_addr, any) != 0) {
00223 LOG2(LOG_ERR, "tunnel add failed (%s => %s)\n",
00224 tunnel_device, inet_ntoa(ma_addr));
00225 return -1;
00226 }
00227
00228 if (dyn_ip_addr_add(tunnel_device, local_addr) != 0) {
00229 DEBUG(DEBUG_INFO, "dyn_ip_addr_add(%s, %s) failed!\n",
00230 tunnel_device,
00231 inet_ntoa(local_addr));
00232 if (dyn_ip_tunnel_del(tunnel_device) != 0) {
00233 DEBUG(DEBUG_INFO, "tunnel delete failed\n");
00234 }
00235 return -1;
00236 }
00237
00238 if (dyn_ip_link_set_dev_up(tunnel_device) != 0) {
00239 DEBUG(DEBUG_INFO,
00240 "dyn_ip_link_set_dev_up(%s) failed!\n",
00241 tunnel_device);
00242 if (dyn_ip_tunnel_del(tunnel_device) != 0) {
00243 DEBUG(DEBUG_INFO, "tunnel delete failed\n");
00244 }
00245 return -1;
00246 }
00247
00248 return 0;
00249 }
00250
00251
00259 int
00260 start_tunneling(void)
00261 {
00262 int failed = 0;
00263
00264 if (real_tunnel_up) {
00265 DEBUG(DEBUG_INFO, "Start tunneling - tunnel is already up\n");
00266 mn.tunnel_up = 1;
00267 return 0;
00268 }
00269
00270 #ifdef MN_ENABLE_TUNNELING
00271
00272 DEBUG(DEBUG_INFO, "Start tunneling - FA addr %s\n",
00273 inet_ntoa(mn.fa_addr));
00274
00275 if (mn.tunnel_mode == API_TUNNEL_FULL_HA) {
00276
00277
00278 if (dyn_ip_route_to_host(config.ha_ip_addr) != 0) {
00279 LOG2(LOG_ERR, "Could not set host route to the HA\n");
00280 }
00281 }
00282
00283 if (!config.enable_fa_decapsulation) {
00284 if (make_tunnel(config.mn_home_ip_addr, mn.fa_addr) < 0)
00285 return -1;
00286
00287 switch (config.mndecaps_route_handling) {
00288 case MNDECAPS_ROUTE_DEFAULT:
00289
00290 DEBUG(DEBUG_INFO, "Setting default route to %s\n",
00291 tunnel_device);
00292 if (dyn_ip_route_replace_default(
00293 tunnel_device, NULL,
00294 &config.mn_home_ip_addr) != 0) {
00295 LOG2(LOG_ERR,
00296 "Set default route to dev %s failed\n",
00297 tunnel_device);
00298 failed = 1;
00299 }
00300 break;
00301 case MNDECAPS_ROUTE_HOME_NET:
00302
00303
00304
00305 DEBUG(DEBUG_INFO, "Setting home net route to %s\n",
00306 tunnel_device);
00307 if (dyn_ip_route_replace_net(tunnel_device,
00308 &config.home_net_addr,
00309 config.home_net_addr_plen)
00310 != 0) {
00311 LOG2(LOG_ERR,
00312 "Set home net route to dev %s failed\n",
00313 tunnel_device);
00314 failed = 1;
00315 }
00316 break;
00317 case MNDECAPS_ROUTE_NONE:
00318 DEBUG(DEBUG_INFO, "No route set to %s\n",
00319 tunnel_device);
00320 break;
00321 }
00322
00323 if (failed) {
00324
00325 if (dyn_ip_tunnel_del(tunnel_device) != 0) {
00326 DEBUG(DEBUG_INFO, "tunnel delete failed\n");
00327 }
00328 return -1;
00329 }
00330 } else if (mn.current_adv != NULL) {
00331
00332
00333
00334 if (update_fa_decaps_routes(mn.current_adv->ifname,
00335 mn.current_adv->ifindex,
00336 mn.fa_addr,
00337 config.home_net_addr,
00338 config.home_net_addr_plen) < 0)
00339 return -1;
00340 } else
00341 LOG2(LOG_WARNING, "start_tunneling() - current_adv == NULL\n");
00342
00343 #else
00344 DEBUG(DEBUG_INFO, "Start tunneling - tunneling disabled\n");
00345 #endif
00346 mn.tunnel_addr.s_addr = mn.fa_addr.s_addr;
00347 mn.tunnel_up = 1;
00348 real_tunnel_up = 1;
00349 return 0;
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359 int restart_tunneling(void)
00360 {
00361 #ifdef MN_ENABLE_TUNNELING
00362 struct in_addr old;
00363
00364
00365 if (!tunnel_b_up) {
00366 dynamics_strlcpy(tunnel_device, TUNNEL_DEVICE_B,
00367 sizeof(tunnel_device));
00368 tunnel_b_up = 1;
00369 } else {
00370 dynamics_strlcpy(tunnel_device, TUNNEL_DEVICE,
00371 sizeof(tunnel_device));
00372 tunnel_b_up = 0;
00373 }
00374 old.s_addr = mn.tunnel_addr.s_addr;
00375
00376 mn.tunnel_up = 0;
00377 real_tunnel_up = 0;
00378 start_tunneling();
00379
00380 if (tunnel_b_up)
00381 dynamics_strlcpy(old_tunnel_device, TUNNEL_DEVICE,
00382 sizeof(old_tunnel_device));
00383 else
00384 dynamics_strlcpy(old_tunnel_device, TUNNEL_DEVICE_B,
00385 sizeof(old_tunnel_device));
00386
00387 if (!config.enable_fa_decapsulation) {
00388
00389 old_tunnel_addr.s_addr = old.s_addr;
00390 old_tunnel_expire = time(NULL) + OLD_TUNNEL_EXTRA_TIME;
00391 }
00392
00393 #else
00394 DEBUG(DEBUG_INFO, "Restart tunneling - tunneling disabled\n");
00395 #endif
00396 return 0;
00397 }
00398
00406 int stop_tunneling(void)
00407 {
00408 int ret = 1;
00409 char dev[IFNAMSIZ], *home_dev = NULL;
00410
00411 #ifdef MN_ENABLE_TUNNELING
00412 DEBUG(DEBUG_INFO, "Stop tunneling\n");
00413
00414 if (mn.current_adv == NULL)
00415 LOG2(LOG_WARNING, "stop_tunneling - current_adv == NULL\n");
00416
00417 if (mn.tunnel_mode == API_TUNNEL_FULL_HA) {
00418
00419 dev[0] = '\0';
00420 if (dyn_ip_route_get(config.ha_ip_addr, dev, IFNAMSIZ) != 0 ||
00421 dyn_ip_route_del(config.ha_ip_addr, dev) != 0) {
00422 LOG2(LOG_ERR, "Could not remove host route to the "
00423 "HA (dev=%s)\n", dev);
00424 }
00425 }
00426
00427 if (config.enable_fa_decapsulation)
00428 home_dev = return_home_net_route();
00429
00430
00431 DEBUG(DEBUG_INFO, "Restoring default route\n");
00432 if (dyn_ip_route_restore_default(home_dev) != 0 &&
00433 device_up(dyn_ip_get_saved_ifindex())) {
00434 LOG2(LOG_ERR, "restoring default route failed\n");
00435 ret = 0;
00436 }
00437
00438 if (config.enable_fa_decapsulation) {
00439 if (mn.current_adv)
00440 remove_fa_host_routes(1);
00441 } else {
00442 if (dyn_ip_tunnel_del(tunnel_device) != 0) {
00443 LOG2(LOG_ERR, "tunnel delete failed\n");
00444 ret = 0;
00445 }
00446 if (old_tunnel_expire != 0 &&
00447 dyn_ip_tunnel_del(old_tunnel_device) != 0) {
00448 LOG2(LOG_ERR, "tunnel delete failed for old tunnel\n");
00449 }
00450 old_tunnel_expire = 0;
00451 }
00452 #else
00453 DEBUG(DEBUG_INFO, "Stop tunneling - tunneling disabled\n");
00454 #endif
00455 mn.tunnel_up = 0;
00456 real_tunnel_up = 0;
00457 if (mn.current_adv != NULL) mn.current_adv->in_use = 0;
00458 return ret;
00459 }