summaryrefslogtreecommitdiff
path: root/lib/nexthop.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/nexthop.c')
-rw-r--r--lib/nexthop.c118
1 files changed, 116 insertions, 2 deletions
diff --git a/lib/nexthop.c b/lib/nexthop.c
index 73c2de0cd8..d2ab70e209 100644
--- a/lib/nexthop.c
+++ b/lib/nexthop.c
@@ -33,6 +33,7 @@
#include "mpls.h"
#include "jhash.h"
#include "printfrr.h"
+#include "vrf.h"
DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop")
DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label")
@@ -117,6 +118,12 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1,
if (next1->type > next2->type)
return 1;
+ if (next1->weight < next2->weight)
+ return -1;
+
+ if (next1->weight > next2->weight)
+ return 1;
+
switch (next1->type) {
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV6:
@@ -200,7 +207,7 @@ int nexthop_same_firsthop(struct nexthop *next1, struct nexthop *next2)
*/
const char *nexthop_type_to_str(enum nexthop_types_t nh_type)
{
- static const char *desc[] = {
+ static const char *const desc[] = {
"none", "Directly connected",
"IPv4 nexthop", "IPv4 nexthop with ifindex",
"IPv6 nexthop", "IPv6 nexthop with ifindex",
@@ -223,7 +230,23 @@ bool nexthop_labels_match(const struct nexthop *nh1, const struct nexthop *nh2)
struct nexthop *nexthop_new(void)
{
- return XCALLOC(MTYPE_NEXTHOP, sizeof(struct nexthop));
+ struct nexthop *nh;
+
+ nh = XCALLOC(MTYPE_NEXTHOP, sizeof(struct nexthop));
+
+ /*
+ * Default the weight to 1 here for all nexthops.
+ * The linux kernel does some weird stuff with adding +1 to
+ * all nexthop weights it gets over netlink.
+ * To handle this, just default everything to 1 right from
+ * from the beggining so we don't have to special case
+ * default weights in the linux netlink code.
+ *
+ * 1 should be a valid on all platforms anyway.
+ */
+ nh->weight = 1;
+
+ return nh;
}
/* Free nexthop. */
@@ -281,6 +304,93 @@ bool nexthop_same_no_labels(const struct nexthop *nh1,
return true;
}
+/*
+ * Allocate a new nexthop object and initialize it from various args.
+ */
+struct nexthop *nexthop_from_ifindex(ifindex_t ifindex, vrf_id_t vrf_id)
+{
+ struct nexthop *nexthop;
+
+ nexthop = nexthop_new();
+ nexthop->type = NEXTHOP_TYPE_IFINDEX;
+ nexthop->ifindex = ifindex;
+ nexthop->vrf_id = vrf_id;
+
+ return nexthop;
+}
+
+struct nexthop *nexthop_from_ipv4(const struct in_addr *ipv4,
+ const struct in_addr *src,
+ vrf_id_t vrf_id)
+{
+ struct nexthop *nexthop;
+
+ nexthop = nexthop_new();
+ nexthop->type = NEXTHOP_TYPE_IPV4;
+ nexthop->vrf_id = vrf_id;
+ nexthop->gate.ipv4 = *ipv4;
+ if (src)
+ nexthop->src.ipv4 = *src;
+
+ return nexthop;
+}
+
+struct nexthop *nexthop_from_ipv4_ifindex(const struct in_addr *ipv4,
+ const struct in_addr *src,
+ ifindex_t ifindex, vrf_id_t vrf_id)
+{
+ struct nexthop *nexthop;
+
+ nexthop = nexthop_new();
+ nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
+ nexthop->vrf_id = vrf_id;
+ nexthop->gate.ipv4 = *ipv4;
+ if (src)
+ nexthop->src.ipv4 = *src;
+ nexthop->ifindex = ifindex;
+
+ return nexthop;
+}
+
+struct nexthop *nexthop_from_ipv6(const struct in6_addr *ipv6,
+ vrf_id_t vrf_id)
+{
+ struct nexthop *nexthop;
+
+ nexthop = nexthop_new();
+ nexthop->vrf_id = vrf_id;
+ nexthop->type = NEXTHOP_TYPE_IPV6;
+ nexthop->gate.ipv6 = *ipv6;
+
+ return nexthop;
+}
+
+struct nexthop *nexthop_from_ipv6_ifindex(const struct in6_addr *ipv6,
+ ifindex_t ifindex, vrf_id_t vrf_id)
+{
+ struct nexthop *nexthop;
+
+ nexthop = nexthop_new();
+ nexthop->vrf_id = vrf_id;
+ nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
+ nexthop->gate.ipv6 = *ipv6;
+ nexthop->ifindex = ifindex;
+
+ return nexthop;
+}
+
+struct nexthop *nexthop_from_blackhole(enum blackhole_type bh_type)
+{
+ struct nexthop *nexthop;
+
+ nexthop = nexthop_new();
+ nexthop->vrf_id = VRF_DEFAULT;
+ nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
+ nexthop->bh_type = bh_type;
+
+ return nexthop;
+}
+
/* Update nexthop with label information. */
void nexthop_add_labels(struct nexthop *nexthop, enum lsp_types_t type,
uint8_t num_labels, mpls_label_t *label)
@@ -288,6 +398,9 @@ void nexthop_add_labels(struct nexthop *nexthop, enum lsp_types_t type,
struct mpls_label_stack *nh_label;
int i;
+ if (num_labels == 0)
+ return;
+
nexthop->nh_label_type = type;
nh_label = XCALLOC(MTYPE_NH_LABEL,
sizeof(struct mpls_label_stack)
@@ -459,6 +572,7 @@ void nexthop_copy(struct nexthop *copy, const struct nexthop *nexthop,
copy->ifindex = nexthop->ifindex;
copy->type = nexthop->type;
copy->flags = nexthop->flags;
+ copy->weight = nexthop->weight;
memcpy(&copy->gate, &nexthop->gate, sizeof(nexthop->gate));
memcpy(&copy->src, &nexthop->src, sizeof(nexthop->src));
memcpy(&copy->rmap_src, &nexthop->rmap_src, sizeof(nexthop->rmap_src));