summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2019-03-22 08:45:48 +0100
committerGitHub <noreply@github.com>2019-03-22 08:45:48 +0100
commit8d39ebf675a8a2fafde0dfa74ed927f364b3c6db (patch)
treef4e61cbdc17f60f34c1e7e510c0a98125bbf8d79 /lib
parentMerge pull request #3972 from mjstapp/fix_privs_race (diff)
parentlib, pbrd: fix indentation of a few commands (diff)
downloadfrr-8d39ebf675a8a2fafde0dfa74ed927f364b3c6db.tar.xz
frr-8d39ebf675a8a2fafde0dfa74ed927f364b3c6db.zip
Merge pull request #3776 from opensourcerouting/pbrd-interface-nexthops
pbrd: add support for interface nexthops
Diffstat (limited to 'lib')
-rw-r--r--lib/nexthop_group.c100
-rw-r--r--lib/nexthop_group.h2
2 files changed, 58 insertions, 44 deletions
diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c
index f940418d8..27ab04279 100644
--- a/lib/nexthop_group.c
+++ b/lib/nexthop_group.c
@@ -188,11 +188,25 @@ static int nhgc_cmp_helper(const char *a, const char *b)
return strcmp(a, b);
}
+static int nhgc_addr_cmp_helper(const union sockunion *a, const union sockunion *b)
+{
+ if (!a && !b)
+ return 0;
+
+ if (a && !b)
+ return -1;
+
+ if (!a && b)
+ return 1;
+
+ return sockunion_cmp(a, b);
+}
+
static int nhgl_cmp(struct nexthop_hold *nh1, struct nexthop_hold *nh2)
{
int ret;
- ret = sockunion_cmp(&nh1->addr, &nh2->addr);
+ ret = nhgc_addr_cmp_helper(nh1->addr, nh2->addr);
if (ret)
return ret;
@@ -209,6 +223,9 @@ static void nhgl_delete(struct nexthop_hold *nh)
XFREE(MTYPE_TMP, nh->nhvrf_name);
+ if (nh->addr)
+ sockunion_free(nh->addr);
+
XFREE(MTYPE_TMP, nh);
}
@@ -292,8 +309,8 @@ static void nexthop_group_save_nhop(struct nexthop_group_cmd *nhgc,
nh->nhvrf_name = XSTRDUP(MTYPE_TMP, nhvrf_name);
if (intf)
nh->intf = XSTRDUP(MTYPE_TMP, intf);
-
- nh->addr = *addr;
+ if (addr)
+ nh->addr = sockunion_dup(addr);
listnode_add_sort(nhgc->nhg_list, nh);
}
@@ -308,7 +325,7 @@ static void nexthop_group_unsave_nhop(struct nexthop_group_cmd *nhgc,
for (ALL_LIST_ELEMENTS_RO(nhgc->nhg_list, node, nh)) {
if (nhgc_cmp_helper(nhvrf_name, nh->nhvrf_name) == 0 &&
- sockunion_cmp(addr, &nh->addr) == 0 &&
+ nhgc_addr_cmp_helper(addr, nh->addr) == 0 &&
nhgc_cmp_helper(intf, nh->intf) == 0)
break;
}
@@ -320,13 +337,7 @@ static void nexthop_group_unsave_nhop(struct nexthop_group_cmd *nhgc,
return;
list_delete_node(nhgc->nhg_list, node);
-
- if (nh->nhvrf_name)
- XFREE(MTYPE_TMP, nh->nhvrf_name);
- if (nh->intf)
- XFREE(MTYPE_TMP, nh->intf);
-
- XFREE(MTYPE_TMP, nh);
+ nhgl_delete(nh);
}
static bool nexthop_group_parse_nexthop(struct nexthop *nhop,
@@ -347,36 +358,45 @@ static bool nexthop_group_parse_nexthop(struct nexthop *nhop,
nhop->vrf_id = vrf->vrf_id;
- if (addr->sa.sa_family == AF_INET) {
- nhop->gate.ipv4.s_addr = addr->sin.sin_addr.s_addr;
- if (intf) {
- nhop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
- nhop->ifindex = ifname2ifindex(intf, vrf->vrf_id);
- if (nhop->ifindex == IFINDEX_INTERNAL)
- return false;
- } else
- nhop->type = NEXTHOP_TYPE_IPV4;
- } else {
- memcpy(&nhop->gate.ipv6, &addr->sin6.sin6_addr, 16);
- if (intf) {
- nhop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
- nhop->ifindex = ifname2ifindex(intf, vrf->vrf_id);
- if (nhop->ifindex == IFINDEX_INTERNAL)
- return false;
- } else
- nhop->type = NEXTHOP_TYPE_IPV6;
+ if (intf) {
+ nhop->ifindex = ifname2ifindex(intf, vrf->vrf_id);
+ if (nhop->ifindex == IFINDEX_INTERNAL)
+ return false;
}
+ if (addr) {
+ if (addr->sa.sa_family == AF_INET) {
+ nhop->gate.ipv4.s_addr = addr->sin.sin_addr.s_addr;
+ if (intf)
+ nhop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
+ else
+ nhop->type = NEXTHOP_TYPE_IPV4;
+ } else {
+ nhop->gate.ipv6 = addr->sin6.sin6_addr;
+ if (intf)
+ nhop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
+ else
+ nhop->type = NEXTHOP_TYPE_IPV6;
+ }
+ } else
+ nhop->type = NEXTHOP_TYPE_IFINDEX;
+
return true;
}
DEFPY(ecmp_nexthops, ecmp_nexthops_cmd,
- "[no] nexthop <A.B.C.D|X:X::X:X>$addr [INTERFACE]$intf [nexthop-vrf NAME$name]",
+ "[no] nexthop\
+ <\
+ <A.B.C.D|X:X::X:X>$addr [INTERFACE$intf]\
+ |INTERFACE$intf\
+ >\
+ [nexthop-vrf NAME$name]",
NO_STR
"Specify one of the nexthops in this ECMP group\n"
"v4 Address\n"
"v6 Address\n"
"Interface to use\n"
+ "Interface to use\n"
"If the nexthop is in a different vrf tell us\n"
"The nexthop-vrf Name\n")
{
@@ -385,13 +405,6 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd,
struct nexthop *nh;
bool legal;
- /*
- * This is impossible to happen as that the cli parser refuses
- * to let you get here without an addr, but the SA system
- * does not understand this intricacy
- */
- assert(addr);
-
legal = nexthop_group_parse_nexthop(&nhop, addr, intf, name);
if (nhop.type == NEXTHOP_TYPE_IPV6
@@ -480,9 +493,10 @@ static void nexthop_group_write_nexthop_internal(struct vty *vty,
{
char buf[100];
- vty_out(vty, "nexthop ");
+ vty_out(vty, "nexthop");
- vty_out(vty, "%s", sockunion2str(&nh->addr, buf, sizeof(buf)));
+ if (nh->addr)
+ vty_out(vty, " %s", sockunion2str(nh->addr, buf, sizeof(buf)));
if (nh->intf)
vty_out(vty, " %s", nh->intf);
@@ -504,7 +518,7 @@ static int nexthop_group_write(struct vty *vty)
vty_out(vty, "nexthop-group %s\n", nhgc->name);
for (ALL_LIST_ELEMENTS_RO(nhgc->nhg_list, node, nh)) {
- vty_out(vty, " ");
+ vty_out(vty, " ");
nexthop_group_write_nexthop_internal(vty, nh);
}
@@ -526,7 +540,7 @@ void nexthop_group_enable_vrf(struct vrf *vrf)
struct nexthop nhop;
struct nexthop *nh;
- if (!nexthop_group_parse_nexthop(&nhop, &nhh->addr,
+ if (!nexthop_group_parse_nexthop(&nhop, nhh->addr,
nhh->intf,
nhh->nhvrf_name))
continue;
@@ -562,7 +576,7 @@ void nexthop_group_disable_vrf(struct vrf *vrf)
struct nexthop nhop;
struct nexthop *nh;
- if (!nexthop_group_parse_nexthop(&nhop, &nhh->addr,
+ if (!nexthop_group_parse_nexthop(&nhop, nhh->addr,
nhh->intf,
nhh->nhvrf_name))
continue;
@@ -600,7 +614,7 @@ void nexthop_group_interface_state_change(struct interface *ifp,
struct nexthop nhop;
if (!nexthop_group_parse_nexthop(
- &nhop, &nhh->addr, nhh->intf,
+ &nhop, nhh->addr, nhh->intf,
nhh->nhvrf_name))
continue;
diff --git a/lib/nexthop_group.h b/lib/nexthop_group.h
index b14cbb5b5..c6e290eee 100644
--- a/lib/nexthop_group.h
+++ b/lib/nexthop_group.h
@@ -68,7 +68,7 @@ void copy_nexthops(struct nexthop **tnh, struct nexthop *nh,
struct nexthop_hold {
char *nhvrf_name;
- union sockunion addr;
+ union sockunion *addr;
char *intf;
};