Ejemplo n.º 1
0
/**
 * Delete a prefix from the prefix tree hanging off a lsdb (tc) entry.
 */
void
olsr_delete_routing_table(union olsr_ip_addr *dst, int plen,
                          union olsr_ip_addr *originator)
{
#ifdef DEBUG
  struct ipaddr_str dstbuf, origbuf;
#endif

  struct tc_entry *tc;
  struct rt_path *rtp;
  struct avl_node *node;
  struct olsr_ip_prefix prefix;

  /*
   * No bogus prefix lengths.
   */
  if (plen > olsr_cnf->maxplen) {
    return;
  }

  tc = olsr_lookup_tc_entry(originator);
  if (!tc) {
    return;
  }

  /*
   * Grab the rt_path for the prefix.
   */
  prefix.prefix = *dst;
  prefix.prefix_len = plen;

  node = avl_find(&tc->prefix_tree, &prefix);

  if (node) {
    rtp = rtp_prefix_tree2rtp(node);
    olsr_delete_rt_path(rtp);

#ifdef DEBUG
    OLSR_PRINTF(1, "RIB: del prefix %s/%u from %s\n",
                olsr_ip_to_string(&dstbuf, dst), plen,
                olsr_ip_to_string(&origbuf, originator));
#endif

    /* overload the hna change bit for flagging a prefix change */
    changes_hna = OLSR_TRUE;
  }
}
Ejemplo n.º 2
0
/**
 * Look through the gateway list and select the best gateway
 * depending on the distance to this router
 */
static void gw_default_choose_gateway(void) {
    uint64_t cost_ipv4_threshold = UINT64_MAX;
    uint64_t cost_ipv6_threshold = UINT64_MAX;
    bool eval_cost_ipv4_threshold = false;
    bool eval_cost_ipv6_threshold = false;
    struct gateway_entry *inet_ipv4 = NULL;
    struct gateway_entry *inet_ipv6 = NULL;
    uint64_t cost_ipv4 = UINT64_MAX;
    uint64_t cost_ipv6 = UINT64_MAX;
    struct gateway_entry *gw;
    struct tc_entry *tc;
    bool dual;

    if (olsr_cnf->smart_gw_thresh) {
        /* determine the path cost thresholds */

        gw = olsr_get_ipv4_inet_gateway();
        if (gw) {
            tc = olsr_lookup_tc_entry(&gw->originator);
            if (tc) {
                uint64_t cost = gw_default_weigh_costs(tc->path_cost, gw->uplink, gw->downlink);
                cost_ipv4_threshold = gw_default_calc_threshold(cost);
                eval_cost_ipv4_threshold = true;
            }
        }
        gw = olsr_get_ipv6_inet_gateway();
        if (gw) {
            tc = olsr_lookup_tc_entry(&gw->originator);
            if (tc) {
                uint64_t cost = gw_default_weigh_costs(tc->path_cost, gw->uplink, gw->downlink);
                cost_ipv6_threshold = gw_default_calc_threshold(cost);
                eval_cost_ipv6_threshold = true;
            }
        }
    }

    OLSR_FOR_ALL_GATEWAY_ENTRIES(gw) {
        uint64_t path_cost;
        tc = olsr_lookup_tc_entry(&gw->originator);

        if (!tc) {
            /* gateways should not exist without tc entry */
            continue;
        }

        if (tc->path_cost == ROUTE_COST_BROKEN) {
            /* do not consider nodes with an infinite ETX */
            continue;
        }

        if (!gw->uplink || !gw->downlink) {
            /* do not consider nodes without bandwidth or with a uni-directional link */
            continue;
        }

        /* determine the path cost */
        path_cost = gw_default_weigh_costs(tc->path_cost, gw->uplink, gw->downlink);

        if (!gw_def_finished_ipv4 && gw->ipv4 && gw->ipv4nat == olsr_cnf->smart_gw_allow_nat && path_cost < cost_ipv4
                && (!eval_cost_ipv4_threshold || (path_cost < cost_ipv4_threshold))) {
            inet_ipv4 = gw;
            cost_ipv4 = path_cost;
        }
        if (!gw_def_finished_ipv6 && gw->ipv6 && path_cost < cost_ipv6
                && (!eval_cost_ipv6_threshold || (path_cost < cost_ipv6_threshold))) {
            inet_ipv6 = gw;
            cost_ipv6 = path_cost;
        }
    }
    OLSR_FOR_ALL_GATEWAY_ENTRIES_END(gw)

    /* determine if we found an IPv4 and IPv6 gateway */
    gw_def_finished_ipv4 |= (inet_ipv4 != NULL);
    gw_def_finished_ipv6 |= (inet_ipv6 != NULL);

    /* determine if we are dealing with a dual stack gateway */
    dual = (inet_ipv4 == inet_ipv6) && (inet_ipv4 != NULL);

    if (inet_ipv4) {
        /* we are dealing with an IPv4 or dual stack gateway */
        olsr_set_inet_gateway(&inet_ipv4->originator, true, dual);
    }
    if (inet_ipv6 && !dual) {
        /* we are dealing with an IPv6-only gateway */
        olsr_set_inet_gateway(&inet_ipv6->originator, false, true);
    }

    if ((olsr_cnf->smart_gw_thresh == 0) && gw_def_finished_ipv4 && gw_def_finished_ipv6) {
        /* stop looking for a better gateway */
        olsr_stop_timer(gw_def_timer);
        gw_def_timer = NULL;
    }
}
Ejemplo n.º 3
0
/**
 * Determine the best gateway for uplink: this is the cluster leader.
 *
 * Loop over all gateways to find the best one and return it.
 * When no best gateway is found then we return ourselves so that the behaviour
 * degrades gracefully.
 *
 * A gateway is better when the sum of its uplink and downlink are greater than
 * the previous best gateway. In case of a tie, the lowest IP address wins.
 *
 * @param bestGateway
 * a pointer to the variable in which to store the best gateway
 */
void getBestUplinkGateway(union olsr_ip_addr * bestGateway) {
	struct gateway_entry *gw_best = NULL;
	unsigned long long gw_best_value = 0;
	struct gateway_entry *gw;

	OLSR_FOR_ALL_GATEWAY_ENTRIES(gw) {
		bool eval4 = false;
		bool eval6 = false;

		struct tc_entry * tc = olsr_lookup_tc_entry(&gw->originator);
		if (!tc || (tc->path_cost == ROUTE_COST_BROKEN) || (!gw->uplink || !gw->downlink)) {
			/* gateways should not exist without tc entry */
			/* do not consider nodes with an infinite ETX */
			/* do not consider nodes without bandwidth or with a uni-directional link */
			continue;
		}

		if (gw == olsr_get_inet_gateway(false)) {
			eval4 = true;
		} else if (gw->ipv4
				&& (olsr_cnf->ip_version == AF_INET || olsr_cnf->use_niit)
				&& (olsr_cnf->smart_gw_allow_nat || !gw->ipv4nat)) {
			eval4 = true;
		}

		if (gw == olsr_get_inet_gateway(true)) {
			eval6 = true;
		} else if (gw->ipv6 && olsr_cnf->ip_version == AF_INET6) {
			eval6 = true;
		}

		if (eval4 || eval6) {
			unsigned long long gw_value = gw_speed(gw);
			if (!gw_best || (gw_value > gw_best_value)) {
				gw_best = gw;
				gw_best_value = gw_value;
			} else if (gw_value == gw_best_value) {
				bool gwHaslowerIpAddress = false;
				if (eval4) {
					gwHaslowerIpAddress = (ip4cmp(&gw->originator.v4,
							&gw_best->originator.v4) < 0);
				} else /* eval6 */{
					gwHaslowerIpAddress = (ip6cmp(&gw->originator.v6,
							&gw_best->originator.v6) < 0);
				}
				if (gwHaslowerIpAddress) {
					gw_best = gw;
					gw_best_value = gw_value;
				}
			}
		}
	} OLSR_FOR_ALL_GATEWAY_ENTRIES_END(gw)

	if (!gw_best) {
		/* degrade gracefully */
		*bestGateway = olsr_cnf->main_addr;
		return;
	}

	*bestGateway = gw_best->originator;
}