#include "log.h"
#include "plist.h"
#include "vrf.h"
+#include "frrstr.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_asbr.h"
#include "ospfd/ospf_lsa.h"
#include "ospfd/ospf_route.h"
#include "ospfd/ospf_zebra.h"
+#include "ospfd/ospf_errors.h"
/* Hook function for updating route_map assignment. */
static void ospf_route_map_update(const char *name)
{
struct ospf *ospf;
int type;
+ struct listnode *n1 = NULL;
/* If OSPF instatnce does not exist, return right now. */
- ospf = ospf_lookup();
- if (ospf == NULL)
+ if (listcount(om->ospf) == 0)
return;
- /* Update route-map */
- for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
- struct list *red_list;
- struct listnode *node;
- struct ospf_redist *red;
-
- red_list = ospf->redist[type];
- if (!red_list)
- continue;
-
- for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
- if (ROUTEMAP_NAME(red)
- && strcmp(ROUTEMAP_NAME(red), name) == 0) {
- /* Keep old route-map. */
- struct route_map *old = ROUTEMAP(red);
-
- /* Update route-map. */
- ROUTEMAP(red) = route_map_lookup_by_name(
- ROUTEMAP_NAME(red));
-
- /* No update for this distribute type. */
- if (old == NULL && ROUTEMAP(red) == NULL)
- continue;
-
- ospf_distribute_list_update(ospf, type,
- red->instance);
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+ /* Update route-map */
+ for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+ struct list *red_list;
+ struct listnode *node;
+ struct ospf_redist *red;
+
+ red_list = ospf->redist[type];
+ if (!red_list)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
+ if (ROUTEMAP_NAME(red)
+ && strcmp(ROUTEMAP_NAME(red), name) == 0) {
+ /* Keep old route-map. */
+ struct route_map *old = ROUTEMAP(red);
+
+ /* Update route-map. */
+ ROUTEMAP(red) =
+ route_map_lookup_by_name(
+ ROUTEMAP_NAME(red));
+
+ /* No update for this distribute type.
+ */
+ if (old == NULL
+ && ROUTEMAP(red) == NULL)
+ continue;
+
+ ospf_distribute_list_update(
+ ospf, type, red->instance);
+ }
}
}
}
{
struct ospf *ospf;
int type;
-
- /* If OSPF instatnce does not exist, return right now. */
- ospf = ospf_lookup();
- if (ospf == NULL)
- return;
-
- for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
- struct list *red_list;
- struct listnode *node;
- struct ospf_redist *red;
-
- red_list = ospf->redist[type];
- if (!red_list)
- continue;
-
- for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
- if (ROUTEMAP_NAME(red) && ROUTEMAP(red)
- && !strcmp(ROUTEMAP_NAME(red), name)) {
- ospf_distribute_list_update(ospf, type,
- red->instance);
+ struct listnode *n1 = NULL;
+
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, n1, ospf)) {
+ for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+ struct list *red_list;
+ struct listnode *node;
+ struct ospf_redist *red;
+
+ red_list = ospf->redist[type];
+ if (!red_list)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
+ if (ROUTEMAP_NAME(red) && ROUTEMAP(red)
+ && !strcmp(ROUTEMAP_NAME(red), name)) {
+ ospf_distribute_list_update(
+ ospf, type, red->instance);
+ }
}
}
}
/* `match ip netxthop ' */
/* Match function return 1 if match is success else return zero. */
static route_map_result_t route_match_ip_nexthop(void *rule,
- struct prefix *prefix,
+ const struct prefix *prefix,
route_map_object_t type,
void *object)
{
/* `match ip next-hop prefix-list PREFIX_LIST' */
static route_map_result_t
-route_match_ip_next_hop_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
struct prefix_list *plist;
/* Match function should return 1 if match is success else return
zero. */
static route_map_result_t route_match_ip_address(void *rule,
- struct prefix *prefix,
+ const struct prefix *prefix,
route_map_object_t type,
void *object)
{
/* `match ip address prefix-list PREFIX_LIST' */
static route_map_result_t
-route_match_ip_address_prefix_list(void *rule, struct prefix *prefix,
+route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
struct prefix_list *plist;
/* Match function should return 1 if match is success else return
zero. */
static route_map_result_t route_match_interface(void *rule,
- struct prefix *prefix,
+ const struct prefix *prefix,
route_map_object_t type,
void *object)
{
if (type == RMAP_OSPF) {
ei = object;
- ifp = if_lookup_by_name((char *)rule, VRF_DEFAULT);
+ ifp = if_lookup_by_name_all_vrf((char *)rule);
if (ifp == NULL || ifp->ifindex != ei->ifindex)
return RMAP_NOMATCH;
route_match_interface_free};
/* Match function return 1 if match is success else return zero. */
-static route_map_result_t route_match_tag(void *rule, struct prefix *prefix,
+static route_map_result_t route_match_tag(void *rule,
+ const struct prefix *prefix,
route_map_object_t type, void *object)
{
route_tag_t *tag;
};
struct ospf_metric {
+ enum { metric_increment, metric_decrement, metric_absolute } type;
bool used;
- u_int32_t metric;
+ uint32_t metric;
};
/* `set metric METRIC' */
/* Set metric to attribute. */
-static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_metric(void *rule,
+ const struct prefix *prefix,
route_map_object_t type,
void *object)
{
ei = object;
/* Set metric out value. */
- if (metric->used)
+ if (!metric->used)
+ return RMAP_OKAY;
+ if (metric->type == metric_increment)
+ ei->route_map_set.metric += metric->metric;
+ if (metric->type == metric_decrement)
+ ei->route_map_set.metric -= metric->metric;
+ if (metric->type == metric_absolute)
ei->route_map_set.metric = metric->metric;
+
+ if ((signed int)ei->route_map_set.metric < 1)
+ ei->route_map_set.metric = -1;
+ if (ei->route_map_set.metric > OSPF_LS_INFINITY)
+ ei->route_map_set.metric = OSPF_LS_INFINITY;
}
return RMAP_OKAY;
}
{
struct ospf_metric *metric;
- metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_int32_t));
+ metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
metric->used = false;
- /* OSPF doesn't support the +/- in
- set metric <+/-metric> check
- Ignore the +/- component */
- if (!all_digit(arg)) {
- if ((arg[0] == '+' || arg[0] == '-') && all_digit(arg + 1)) {
- zlog_warn("OSPF does not support 'set metric +/-'");
- arg++;
- } else {
- if (strmatch(arg, "+rtt") || strmatch(arg, "-rtt"))
- zlog_warn(
- "OSPF does not support 'set metric +rtt / -rtt'");
-
- return metric;
- }
+ if (all_digit(arg))
+ metric->type = metric_absolute;
+
+ if (strmatch(arg, "+rtt") || strmatch(arg, "-rtt")) {
+ flog_warn(EC_OSPF_SET_METRIC_PLUS,
+ "OSPF does not support 'set metric +rtt / -rtt'");
+ return metric;
+ }
+
+ if ((arg[0] == '+') && all_digit(arg + 1)) {
+ metric->type = metric_increment;
+ arg++;
+ }
+
+ if ((arg[0] == '-') && all_digit(arg + 1)) {
+ metric->type = metric_decrement;
+ arg++;
}
+
metric->metric = strtoul(arg, NULL, 10);
- metric->used = true;
+
+ if (metric->metric)
+ metric->used = true;
return metric;
}
/* `set metric-type TYPE' */
/* Set metric-type to attribute. */
static route_map_result_t route_set_metric_type(void *rule,
- struct prefix *prefix,
+ const struct prefix *prefix,
route_map_object_t type,
void *object)
{
- u_int32_t *metric_type;
+ uint32_t *metric_type;
struct external_info *ei;
if (type == RMAP_OSPF) {
/* set metric-type compilation. */
static void *route_set_metric_type_compile(const char *arg)
{
- u_int32_t *metric_type;
+ uint32_t *metric_type;
- metric_type = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_int32_t));
+ metric_type = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
if (strcmp(arg, "type-1") == 0)
*metric_type = EXTERNAL_METRIC_TYPE_1;
else if (strcmp(arg, "type-2") == 0)
route_set_metric_type_free,
};
-static route_map_result_t route_set_tag(void *rule, struct prefix *prefix,
+static route_map_result_t route_set_tag(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
route_tag_t *tag;