mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-12 22:28:44 +00:00
Merge commit 'd8661a4397e4576ac404661b192dd99d928e7890' into haugesund
This commit is contained in:
commit
674587d9c8
@ -87,7 +87,6 @@ typedef struct rta {
|
|||||||
struct ea_list *eattrs; /* Extended Attribute chain */
|
struct ea_list *eattrs; /* Extended Attribute chain */
|
||||||
struct hostentry *hostentry; /* Hostentry for recursive next-hops */
|
struct hostentry *hostentry; /* Hostentry for recursive next-hops */
|
||||||
ip_addr from; /* Advertising router */
|
ip_addr from; /* Advertising router */
|
||||||
u32 igp_metric; /* IGP metric to next hop (for iBGP routes) */
|
|
||||||
u16 cached:1; /* Are attributes cached? */
|
u16 cached:1; /* Are attributes cached? */
|
||||||
u16 source:7; /* Route source (RTS_...) */
|
u16 source:7; /* Route source (RTS_...) */
|
||||||
u16 scope:4; /* Route scope (SCOPE_... -- see ip.h) */
|
u16 scope:4; /* Route scope (SCOPE_... -- see ip.h) */
|
||||||
@ -120,10 +119,6 @@ typedef struct rta {
|
|||||||
#define RTD_PROHIBIT 4 /* Administratively prohibited */
|
#define RTD_PROHIBIT 4 /* Administratively prohibited */
|
||||||
#define RTD_MAX 5
|
#define RTD_MAX 5
|
||||||
|
|
||||||
#define IGP_METRIC_UNKNOWN 0x80000000 /* Default igp_metric used when no other
|
|
||||||
protocol-specific metric is availabe */
|
|
||||||
|
|
||||||
|
|
||||||
extern const char * rta_dest_names[RTD_MAX];
|
extern const char * rta_dest_names[RTD_MAX];
|
||||||
|
|
||||||
static inline const char *rta_dest_name(uint n)
|
static inline const char *rta_dest_name(uint n)
|
||||||
@ -188,6 +183,8 @@ struct ea_class_ref {
|
|||||||
struct ea_class *class;
|
struct ea_class *class;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define IGP_METRIC_UNKNOWN 0x80000000 /* Default igp_metric used when no other
|
||||||
|
protocol-specific metric is availabe */
|
||||||
extern struct ea_class ea_gen_igp_metric;
|
extern struct ea_class ea_gen_igp_metric;
|
||||||
|
|
||||||
void ea_register_init(struct ea_class *);
|
void ea_register_init(struct ea_class *);
|
||||||
@ -324,6 +321,6 @@ void rta_dump(rta *);
|
|||||||
void rta_dump_all(void);
|
void rta_dump_all(void);
|
||||||
void rta_show(struct cli *, rta *);
|
void rta_show(struct cli *, rta *);
|
||||||
|
|
||||||
u32 rt_get_igp_metric(rte *rt);
|
u32 rt_get_igp_metric(const rte *rt);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -192,7 +192,7 @@ struct proto {
|
|||||||
struct rte *(*rte_modify)(struct rte *, struct linpool *);
|
struct rte *(*rte_modify)(struct rte *, struct linpool *);
|
||||||
void (*rte_insert)(struct network *, struct rte *);
|
void (*rte_insert)(struct network *, struct rte *);
|
||||||
void (*rte_remove)(struct network *, struct rte *);
|
void (*rte_remove)(struct network *, struct rte *);
|
||||||
u32 (*rte_igp_metric)(struct rte *);
|
u32 (*rte_igp_metric)(const struct rte *);
|
||||||
|
|
||||||
/* Hic sunt protocol-specific data */
|
/* Hic sunt protocol-specific data */
|
||||||
};
|
};
|
||||||
|
@ -1225,7 +1225,6 @@ rta_hash(rta *a)
|
|||||||
#define BMIX(f) mem_hash_mix_num(&h, a->f);
|
#define BMIX(f) mem_hash_mix_num(&h, a->f);
|
||||||
MIX(hostentry);
|
MIX(hostentry);
|
||||||
MIX(from);
|
MIX(from);
|
||||||
MIX(igp_metric);
|
|
||||||
BMIX(source);
|
BMIX(source);
|
||||||
BMIX(scope);
|
BMIX(scope);
|
||||||
BMIX(dest);
|
BMIX(dest);
|
||||||
@ -1241,7 +1240,6 @@ rta_same(rta *x, rta *y)
|
|||||||
return (x->source == y->source &&
|
return (x->source == y->source &&
|
||||||
x->scope == y->scope &&
|
x->scope == y->scope &&
|
||||||
x->dest == y->dest &&
|
x->dest == y->dest &&
|
||||||
x->igp_metric == y->igp_metric &&
|
|
||||||
ipa_equal(x->from, y->from) &&
|
ipa_equal(x->from, y->from) &&
|
||||||
x->hostentry == y->hostentry &&
|
x->hostentry == y->hostentry &&
|
||||||
nexthop_same(&(x->nh), &(y->nh)) &&
|
nexthop_same(&(x->nh), &(y->nh)) &&
|
||||||
|
@ -2505,7 +2505,8 @@ rta_apply_hostentry(rta *a, struct hostentry *he, mpls_label_stack *mls)
|
|||||||
{
|
{
|
||||||
a->hostentry = he;
|
a->hostentry = he;
|
||||||
a->dest = he->dest;
|
a->dest = he->dest;
|
||||||
a->igp_metric = he->igp_metric;
|
|
||||||
|
ea_set_attr_u32(&a->eattrs, &ea_gen_igp_metric, 0, he->igp_metric);
|
||||||
|
|
||||||
if (a->dest != RTD_UNICAST)
|
if (a->dest != RTD_UNICAST)
|
||||||
{
|
{
|
||||||
@ -2602,7 +2603,8 @@ rta_next_hop_outdated(rta *a)
|
|||||||
if (!he->src)
|
if (!he->src)
|
||||||
return a->dest != RTD_UNREACHABLE;
|
return a->dest != RTD_UNREACHABLE;
|
||||||
|
|
||||||
return (a->dest != he->dest) || (a->igp_metric != he->igp_metric) ||
|
return (a->dest != he->dest) ||
|
||||||
|
(ea_get_int(a->eattrs, &ea_gen_igp_metric, IGP_METRIC_UNKNOWN) != he->igp_metric) ||
|
||||||
(!he->nexthop_linkable) || !nexthop_same(&(a->nh), &(he->src->nh));
|
(!he->nexthop_linkable) || !nexthop_same(&(a->nh), &(he->src->nh));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3534,7 +3536,7 @@ if_local_addr(ip_addr a, struct iface *i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
u32
|
u32
|
||||||
rt_get_igp_metric(rte *rt)
|
rt_get_igp_metric(const rte *rt)
|
||||||
{
|
{
|
||||||
eattr *ea = ea_find(rt->attrs->eattrs, "igp_metric");
|
eattr *ea = ea_find(rt->attrs->eattrs, "igp_metric");
|
||||||
|
|
||||||
|
@ -2344,7 +2344,7 @@ babel_rte_better(struct rte *new, struct rte *old)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
babel_rte_igp_metric(struct rte *rt)
|
babel_rte_igp_metric(const rte *rt)
|
||||||
{
|
{
|
||||||
return ea_get_int(rt->attrs->eattrs, &ea_babel_metric, BABEL_INFINITY);
|
return ea_get_int(rt->attrs->eattrs, &ea_babel_metric, BABEL_INFINITY);
|
||||||
}
|
}
|
||||||
|
@ -372,8 +372,10 @@ bgp_aigp_set_metric(struct linpool *pool, const struct adata *ad, u64 metric)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
bgp_total_aigp_metric_(struct rta *a, u64 *metric, const struct adata **ad)
|
bgp_total_aigp_metric_(const rte *e, u64 *metric, const struct adata **ad)
|
||||||
{
|
{
|
||||||
|
rta *a = e->attrs;
|
||||||
|
|
||||||
eattr *ea = ea_find(a->eattrs, BGP_EA_ID(BA_AIGP));
|
eattr *ea = ea_find(a->eattrs, BGP_EA_ID(BA_AIGP));
|
||||||
if (!ea)
|
if (!ea)
|
||||||
return 0;
|
return 0;
|
||||||
@ -383,7 +385,7 @@ bgp_total_aigp_metric_(struct rta *a, u64 *metric, const struct adata **ad)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
u64 aigp = get_u64(b + 3);
|
u64 aigp = get_u64(b + 3);
|
||||||
u64 step = a->igp_metric;
|
u64 step = rt_get_igp_metric(e);
|
||||||
|
|
||||||
if (!rta_resolvable(a) || (step >= IGP_METRIC_UNKNOWN))
|
if (!rta_resolvable(a) || (step >= IGP_METRIC_UNKNOWN))
|
||||||
step = BGP_AIGP_MAX;
|
step = BGP_AIGP_MAX;
|
||||||
@ -411,9 +413,9 @@ bgp_init_aigp_metric(rte *e, u64 *metric, const struct adata **ad)
|
|||||||
}
|
}
|
||||||
|
|
||||||
u32
|
u32
|
||||||
bgp_rte_igp_metric(struct rte *rt)
|
bgp_rte_igp_metric(const rte *rt)
|
||||||
{
|
{
|
||||||
u64 metric = bgp_total_aigp_metric(rt->attrs);
|
u64 metric = bgp_total_aigp_metric(rt);
|
||||||
return (u32) MIN(metric, (u64) IGP_METRIC_UNKNOWN);
|
return (u32) MIN(metric, (u64) IGP_METRIC_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1814,7 +1816,7 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at
|
|||||||
/* AIGP attribute - accumulate local metric or originate new one */
|
/* AIGP attribute - accumulate local metric or originate new one */
|
||||||
u64 metric;
|
u64 metric;
|
||||||
if (s.local_next_hop &&
|
if (s.local_next_hop &&
|
||||||
(bgp_total_aigp_metric_(e->attrs, &metric, &ad) ||
|
(bgp_total_aigp_metric_(e, &metric, &ad) ||
|
||||||
(c->cf->aigp_originate && bgp_init_aigp_metric(e, &metric, &ad))))
|
(c->cf->aigp_originate && bgp_init_aigp_metric(e, &metric, &ad))))
|
||||||
{
|
{
|
||||||
ad = bgp_aigp_set_metric(pool, ad, metric);
|
ad = bgp_aigp_set_metric(pool, ad, metric);
|
||||||
@ -1986,8 +1988,8 @@ bgp_rte_better(rte *new, rte *old)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* RFC 7311 4.1 - Apply AIGP metric */
|
/* RFC 7311 4.1 - Apply AIGP metric */
|
||||||
u64 n2 = bgp_total_aigp_metric(new->attrs);
|
u64 n2 = bgp_total_aigp_metric(new);
|
||||||
u64 o2 = bgp_total_aigp_metric(old->attrs);
|
u64 o2 = bgp_total_aigp_metric(old);
|
||||||
if (n2 < o2)
|
if (n2 < o2)
|
||||||
return 1;
|
return 1;
|
||||||
if (n2 > o2)
|
if (n2 > o2)
|
||||||
@ -2047,8 +2049,8 @@ bgp_rte_better(rte *new, rte *old)
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* RFC 4271 9.1.2.2. e) Compare IGP metrics */
|
/* RFC 4271 9.1.2.2. e) Compare IGP metrics */
|
||||||
n = new_bgp->cf->igp_metric ? new->attrs->igp_metric : 0;
|
n = new_bgp->cf->igp_metric ? rt_get_igp_metric(new) : 0;
|
||||||
o = old_bgp->cf->igp_metric ? old->attrs->igp_metric : 0;
|
o = old_bgp->cf->igp_metric ? rt_get_igp_metric(old) : 0;
|
||||||
if (n < o)
|
if (n < o)
|
||||||
return 1;
|
return 1;
|
||||||
if (n > o)
|
if (n > o)
|
||||||
@ -2156,8 +2158,8 @@ bgp_rte_mergable(rte *pri, rte *sec)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* RFC 4271 9.1.2.2. e) Compare IGP metrics */
|
/* RFC 4271 9.1.2.2. e) Compare IGP metrics */
|
||||||
p = pri_bgp->cf->igp_metric ? pri->attrs->igp_metric : 0;
|
p = pri_bgp->cf->igp_metric ? rt_get_igp_metric(pri) : 0;
|
||||||
s = sec_bgp->cf->igp_metric ? sec->attrs->igp_metric : 0;
|
s = sec_bgp->cf->igp_metric ? rt_get_igp_metric(sec) : 0;
|
||||||
if (p != s)
|
if (p != s)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -2394,19 +2396,19 @@ bgp_get_route_info(rte *e, byte *buf)
|
|||||||
if (rte_stale(e))
|
if (rte_stale(e))
|
||||||
buf += bsprintf(buf, "s");
|
buf += bsprintf(buf, "s");
|
||||||
|
|
||||||
u64 metric = bgp_total_aigp_metric(e->attrs);
|
u64 metric = bgp_total_aigp_metric(e);
|
||||||
if (metric < BGP_AIGP_MAX)
|
if (metric < BGP_AIGP_MAX)
|
||||||
{
|
{
|
||||||
buf += bsprintf(buf, "/%lu", metric);
|
buf += bsprintf(buf, "/%lu", metric);
|
||||||
}
|
}
|
||||||
else if (e->attrs->igp_metric)
|
else if (metric = rt_get_igp_metric(e))
|
||||||
{
|
{
|
||||||
if (!rta_resolvable(e->attrs))
|
if (!rta_resolvable(e->attrs))
|
||||||
buf += bsprintf(buf, "/-");
|
buf += bsprintf(buf, "/-");
|
||||||
else if (e->attrs->igp_metric >= IGP_METRIC_UNKNOWN)
|
else if (metric >= IGP_METRIC_UNKNOWN)
|
||||||
buf += bsprintf(buf, "/?");
|
buf += bsprintf(buf, "/?");
|
||||||
else
|
else
|
||||||
buf += bsprintf(buf, "/%d", e->attrs->igp_metric);
|
buf += bsprintf(buf, "/%d", metric);
|
||||||
}
|
}
|
||||||
buf += bsprintf(buf, ") [");
|
buf += bsprintf(buf, ") [");
|
||||||
|
|
||||||
|
@ -566,22 +566,22 @@ int bgp_rte_better(struct rte *, struct rte *);
|
|||||||
int bgp_rte_mergable(rte *pri, rte *sec);
|
int bgp_rte_mergable(rte *pri, rte *sec);
|
||||||
int bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best);
|
int bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best);
|
||||||
struct rte *bgp_rte_modify_stale(struct rte *r, struct linpool *pool);
|
struct rte *bgp_rte_modify_stale(struct rte *r, struct linpool *pool);
|
||||||
u32 bgp_rte_igp_metric(struct rte *);
|
u32 bgp_rte_igp_metric(const rte *);
|
||||||
void bgp_rt_notify(struct proto *P, struct channel *C, const net_addr *n, rte *new, const rte *old);
|
void bgp_rt_notify(struct proto *P, struct channel *C, const net_addr *n, rte *new, const rte *old);
|
||||||
int bgp_preexport(struct channel *, struct rte *);
|
int bgp_preexport(struct channel *, struct rte *);
|
||||||
void bgp_get_route_info(struct rte *, byte *);
|
void bgp_get_route_info(struct rte *, byte *);
|
||||||
int bgp_total_aigp_metric_(rta *a, u64 *metric, const struct adata **ad);
|
int bgp_total_aigp_metric_(const rte *e, u64 *metric, const struct adata **ad);
|
||||||
|
|
||||||
#define BGP_AIGP_METRIC 1
|
#define BGP_AIGP_METRIC 1
|
||||||
#define BGP_AIGP_MAX U64(0xffffffffffffffff)
|
#define BGP_AIGP_MAX U64(0xffffffffffffffff)
|
||||||
|
|
||||||
static inline u64
|
static inline u64
|
||||||
bgp_total_aigp_metric(rta *a)
|
bgp_total_aigp_metric(const rte *e)
|
||||||
{
|
{
|
||||||
u64 metric = BGP_AIGP_MAX;
|
u64 metric = BGP_AIGP_MAX;
|
||||||
const struct adata *ad;
|
const struct adata *ad;
|
||||||
|
|
||||||
bgp_total_aigp_metric_(a, &metric, &ad);
|
bgp_total_aigp_metric_(e, &metric, &ad);
|
||||||
return metric;
|
return metric;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -969,7 +969,7 @@ bgp_apply_next_hop(struct bgp_parse_state *s, rta *a, ip_addr gw, ip_addr ll)
|
|||||||
a->dest = RTD_UNICAST;
|
a->dest = RTD_UNICAST;
|
||||||
a->nh.gw = nbr->addr;
|
a->nh.gw = nbr->addr;
|
||||||
a->nh.iface = nbr->iface;
|
a->nh.iface = nbr->iface;
|
||||||
a->igp_metric = c->cf->cost;
|
ea_set_attr_u32(&a->eattrs, &ea_gen_igp_metric, 0, c->cf->cost);
|
||||||
}
|
}
|
||||||
else /* GW_RECURSIVE */
|
else /* GW_RECURSIVE */
|
||||||
{
|
{
|
||||||
|
@ -111,7 +111,7 @@
|
|||||||
static int ospf_preexport(struct channel *C, rte *new);
|
static int ospf_preexport(struct channel *C, rte *new);
|
||||||
static void ospf_reload_routes(struct channel *C);
|
static void ospf_reload_routes(struct channel *C);
|
||||||
static int ospf_rte_better(struct rte *new, struct rte *old);
|
static int ospf_rte_better(struct rte *new, struct rte *old);
|
||||||
static u32 ospf_rte_igp_metric(struct rte *rt);
|
static u32 ospf_rte_igp_metric(const rte *rt);
|
||||||
static void ospf_disp(timer *timer);
|
static void ospf_disp(timer *timer);
|
||||||
|
|
||||||
|
|
||||||
@ -411,7 +411,7 @@ ospf_rte_better(struct rte *new, struct rte *old)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
ospf_rte_igp_metric(struct rte *rt)
|
ospf_rte_igp_metric(const rte *rt)
|
||||||
{
|
{
|
||||||
if (rt->attrs->source == RTS_OSPF_EXT2)
|
if (rt->attrs->source == RTS_OSPF_EXT2)
|
||||||
return IGP_METRIC_UNKNOWN;
|
return IGP_METRIC_UNKNOWN;
|
||||||
|
@ -1103,7 +1103,7 @@ rip_rte_better(struct rte *new, struct rte *old)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
rip_rte_igp_metric(struct rte *rt)
|
rip_rte_igp_metric(const rte *rt)
|
||||||
{
|
{
|
||||||
return ea_get_int(rt->attrs->eattrs, &ea_rip_metric, IGP_METRIC_UNKNOWN);
|
return ea_get_int(rt->attrs->eattrs, &ea_rip_metric, IGP_METRIC_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user