mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
Merge pull request #15627 from Max-Mustermann33/ospf6d_metric_for_type5_lsa
ospf6d: Fix metric when sending AS-external LSAs
This commit is contained in:
commit
e941145272
|
@ -33,11 +33,12 @@ struct ospf6_inter_router_lsa {
|
|||
uint32_t router_id;
|
||||
};
|
||||
|
||||
#define OSPF6_ABR_SUMMARY_METRIC(E) (ntohl ((E)->metric & htonl (0x00ffffff)))
|
||||
#define OSPF6_ABR_SUMMARY_METRIC(E) \
|
||||
(ntohl((E)->metric & htonl(OSPF6_EXT_PATH_METRIC_MAX)))
|
||||
#define OSPF6_ABR_SUMMARY_METRIC_SET(E, C) \
|
||||
{ \
|
||||
(E)->metric &= htonl(0x00000000); \
|
||||
(E)->metric |= htonl(0x00ffffff) & htonl(C); \
|
||||
(E)->metric |= htonl(OSPF6_EXT_PATH_METRIC_MAX) & htonl(C); \
|
||||
}
|
||||
|
||||
#define OSPF6_ABR_RANGE_CLEAR_COST(range) (range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "table.h"
|
||||
#include "plist.h"
|
||||
#include "frrevent.h"
|
||||
#include "frrstr.h"
|
||||
#include "linklist.h"
|
||||
#include "lib/northbound_cli.h"
|
||||
|
||||
|
@ -1426,10 +1427,9 @@ static void ospf6_external_lsa_fwd_addr_set(struct ospf6 *ospf6,
|
|||
}
|
||||
|
||||
void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
|
||||
struct prefix *prefix,
|
||||
unsigned int nexthop_num,
|
||||
const struct in6_addr *nexthop,
|
||||
route_tag_t tag, struct ospf6 *ospf6)
|
||||
struct prefix *prefix, unsigned int nexthop_num,
|
||||
const struct in6_addr *nexthop, route_tag_t tag,
|
||||
struct ospf6 *ospf6, uint32_t metric)
|
||||
{
|
||||
route_map_result_t ret;
|
||||
struct ospf6_route troute;
|
||||
|
@ -1472,6 +1472,7 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
|
|||
if (ROUTEMAP(red)) {
|
||||
troute.route_option = &tinfo;
|
||||
troute.ospf6 = ospf6;
|
||||
troute.path.redistribute_cost = metric;
|
||||
tinfo.ifindex = ifindex;
|
||||
tinfo.tag = tag;
|
||||
|
||||
|
@ -1924,7 +1925,7 @@ static void ospf6_redistribute_default_set(struct ospf6 *ospf6, int originate)
|
|||
case DEFAULT_ORIGINATE_ALWAYS:
|
||||
ospf6_asbr_redistribute_add(DEFAULT_ROUTE, 0,
|
||||
(struct prefix *)&p, 0, &nexthop, 0,
|
||||
ospf6);
|
||||
ospf6, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2153,25 +2154,81 @@ static const struct route_map_rule_cmd
|
|||
ospf6_routemap_rule_set_metric_type_free,
|
||||
};
|
||||
|
||||
struct ospf6_metric {
|
||||
enum { metric_increment, metric_decrement, metric_absolute } type;
|
||||
bool used;
|
||||
uint32_t metric;
|
||||
};
|
||||
|
||||
static enum route_map_cmd_result_t
|
||||
ospf6_routemap_rule_set_metric(void *rule, const struct prefix *prefix,
|
||||
void *object)
|
||||
{
|
||||
char *metric = rule;
|
||||
struct ospf6_route *route = object;
|
||||
struct ospf6_metric *metric;
|
||||
struct ospf6_route *route;
|
||||
|
||||
/* Fetch routemap's rule information. */
|
||||
metric = rule;
|
||||
route = object;
|
||||
|
||||
/* Set metric out value. */
|
||||
if (!metric->used)
|
||||
return RMAP_OKAY;
|
||||
|
||||
if (route->path.redistribute_cost > OSPF6_EXT_PATH_METRIC_MAX)
|
||||
route->path.redistribute_cost = OSPF6_EXT_PATH_METRIC_MAX;
|
||||
|
||||
if (metric->type == metric_increment) {
|
||||
route->path.cost = route->path.redistribute_cost +
|
||||
metric->metric;
|
||||
|
||||
/* Check overflow */
|
||||
if (route->path.cost > OSPF6_EXT_PATH_METRIC_MAX ||
|
||||
route->path.cost < metric->metric)
|
||||
route->path.cost = OSPF6_EXT_PATH_METRIC_MAX;
|
||||
} else if (metric->type == metric_decrement) {
|
||||
route->path.cost = route->path.redistribute_cost -
|
||||
metric->metric;
|
||||
|
||||
/* Check overflow */
|
||||
if (route->path.cost == 0 ||
|
||||
route->path.cost > route->path.redistribute_cost)
|
||||
route->path.cost = 1;
|
||||
} else if (metric->type == metric_absolute)
|
||||
route->path.cost = metric->metric;
|
||||
|
||||
route->path.cost = atoi(metric);
|
||||
return RMAP_OKAY;
|
||||
}
|
||||
|
||||
static void *ospf6_routemap_rule_set_metric_compile(const char *arg)
|
||||
{
|
||||
uint32_t metric;
|
||||
char *endp;
|
||||
metric = strtoul(arg, &endp, 0);
|
||||
if (metric > OSPF_LS_INFINITY || *endp != '\0')
|
||||
return NULL;
|
||||
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
|
||||
struct ospf6_metric *metric;
|
||||
|
||||
metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*metric));
|
||||
metric->used = false;
|
||||
|
||||
if (all_digit(arg))
|
||||
metric->type = metric_absolute;
|
||||
|
||||
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);
|
||||
|
||||
if (metric->metric > OSPF6_EXT_PATH_METRIC_MAX)
|
||||
metric->metric = OSPF6_EXT_PATH_METRIC_MAX;
|
||||
|
||||
if (metric->metric)
|
||||
metric->used = true;
|
||||
|
||||
return metric;
|
||||
}
|
||||
|
||||
static void ospf6_routemap_rule_set_metric_free(void *rule)
|
||||
|
|
|
@ -94,11 +94,13 @@ struct ospf6_as_external_lsa {
|
|||
#define OSPF6_ASBR_BIT_F ntohl (0x02000000)
|
||||
#define OSPF6_ASBR_BIT_E ntohl (0x04000000)
|
||||
|
||||
#define OSPF6_ASBR_METRIC(E) (ntohl ((E)->bits_metric & htonl (0x00ffffff)))
|
||||
#define OSPF6_ASBR_METRIC(E) \
|
||||
(ntohl((E)->bits_metric & htonl(OSPF6_EXT_PATH_METRIC_MAX)))
|
||||
#define OSPF6_ASBR_METRIC_SET(E, C) \
|
||||
{ \
|
||||
(E)->bits_metric &= htonl(0xff000000); \
|
||||
(E)->bits_metric |= htonl(0x00ffffff) & htonl(C); \
|
||||
(E)->bits_metric &= htonl(~OSPF6_EXT_PATH_METRIC_MAX); \
|
||||
(E)->bits_metric |= htonl(OSPF6_EXT_PATH_METRIC_MAX) & \
|
||||
htonl(C); \
|
||||
}
|
||||
|
||||
extern void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa);
|
||||
|
@ -115,7 +117,8 @@ extern void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
|
|||
struct prefix *prefix,
|
||||
unsigned int nexthop_num,
|
||||
const struct in6_addr *nexthop,
|
||||
route_tag_t tag, struct ospf6 *ospf6);
|
||||
route_tag_t tag, struct ospf6 *ospf6,
|
||||
uint32_t metric);
|
||||
extern void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex,
|
||||
struct prefix *prefix,
|
||||
struct ospf6 *ospf6);
|
||||
|
|
|
@ -115,6 +115,7 @@ struct ospf6_path {
|
|||
/* Cost */
|
||||
uint8_t metric_type;
|
||||
uint32_t cost;
|
||||
uint32_t redistribute_cost;
|
||||
|
||||
struct prefix ls_prefix;
|
||||
|
||||
|
@ -139,6 +140,8 @@ struct ospf6_path {
|
|||
|
||||
#define OSPF6_PATH_COST_IS_CONFIGURED(path) (path.u.cost_config != OSPF_AREA_RANGE_COST_UNSPEC)
|
||||
|
||||
#define OSPF6_EXT_PATH_METRIC_MAX 0x00ffffff
|
||||
|
||||
#include "prefix.h"
|
||||
#include "table.h"
|
||||
#include "bitfield.h"
|
||||
|
|
|
@ -289,7 +289,7 @@ static int ospf6_zebra_read_route(ZAPI_CALLBACK_ARGS)
|
|||
if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
|
||||
ospf6_asbr_redistribute_add(api.type, ifindex, &api.prefix,
|
||||
api.nexthop_num, nexthop, api.tag,
|
||||
ospf6);
|
||||
ospf6, api.metric);
|
||||
else
|
||||
ospf6_asbr_redistribute_remove(api.type, ifindex, &api.prefix,
|
||||
ospf6);
|
||||
|
|
Loading…
Reference in a new issue