summaryrefslogtreecommitdiff
path: root/ospf6d/ospf6_zebra.c
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@cumulusnetworks.com>2016-10-21 19:27:49 +0000
committerQuentin Young <qlyoung@cumulusnetworks.com>2016-10-21 19:27:49 +0000
commit39e92c066f210b0b550489e98d3b767ee1553e52 (patch)
tree70928b277635d25cb717b8ceb103dd1d5e26f732 /ospf6d/ospf6_zebra.c
parent630a298ca76a0e37c263dc1d2c3053cbddc9ccb3 (diff)
parentce01a2ca3f4501b75e55fe325c150eb9c2ae329d (diff)
Merge branch 'cmaster-next' into vtysh-grammar
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com> Conflicts: bgpd/bgp_encap.c bgpd/bgp_route.c lib/command.c lib/command.h ospf6d/ospf6d.c vtysh/vtysh.c
Diffstat (limited to 'ospf6d/ospf6_zebra.c')
-rw-r--r--ospf6d/ospf6_zebra.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index c3b8739532..a5303fb1b8 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -40,6 +40,8 @@
#include "ospf6_zebra.h"
#include "ospf6d.h"
+DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance")
+
unsigned char conf_debug_ospf6_zebra = 0;
/* information about zebra. */
@@ -456,6 +458,10 @@ ospf6_zebra_route_update (int type, struct ospf6_route *request)
}
dest = (struct prefix_ipv6 *) &request->prefix;
+
+ SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
+ api.distance = ospf6_distance_apply (dest, request);
+
if (type == REM)
ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, &api);
else
@@ -640,6 +646,150 @@ DEFUN (no_redistribute_ospf6,
return CMD_SUCCESS;
}
+static struct ospf6_distance *
+ospf6_distance_new (void)
+{
+ return XCALLOC (MTYPE_OSPF6_DISTANCE, sizeof (struct ospf6_distance));
+}
+
+static void
+ospf6_distance_free (struct ospf6_distance *odistance)
+{
+ XFREE (MTYPE_OSPF6_DISTANCE, odistance);
+}
+
+int
+ospf6_distance_set (struct vty *vty, struct ospf6 *o,
+ const char *distance_str,
+ const char *ip_str,
+ const char *access_list_str)
+{
+ int ret;
+ struct prefix_ipv6 p;
+ u_char distance;
+ struct route_node *rn;
+ struct ospf6_distance *odistance;
+
+ ret = str2prefix_ipv6 (ip_str, &p);
+ if (ret == 0)
+ {
+ vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ distance = atoi (distance_str);
+
+ /* Get OSPF6 distance node. */
+ rn = route_node_get (o->distance_table, (struct prefix *) &p);
+ if (rn->info)
+ {
+ odistance = rn->info;
+ route_unlock_node (rn);
+ }
+ else
+ {
+ odistance = ospf6_distance_new ();
+ rn->info = odistance;
+ }
+
+ /* Set distance value. */
+ odistance->distance = distance;
+
+ /* Reset access-list configuration. */
+ if (odistance->access_list)
+ {
+ free (odistance->access_list);
+ odistance->access_list = NULL;
+ }
+ if (access_list_str)
+ odistance->access_list = strdup (access_list_str);
+
+ return CMD_SUCCESS;
+}
+
+int
+ospf6_distance_unset (struct vty *vty, struct ospf6 *o,
+ const char *distance_str,
+ const char *ip_str,
+ const char *access_list_str)
+{
+ int ret;
+ struct prefix_ipv6 p;
+ struct route_node *rn;
+ struct ospf6_distance *odistance;
+
+ ret = str2prefix_ipv6 (ip_str, &p);
+ if (ret == 0)
+ {
+ vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ rn = route_node_lookup (o->distance_table, (struct prefix *) &p);
+ if (!rn)
+ {
+ vty_out (vty, "Cant't find specified prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ odistance = rn->info;
+
+ if (odistance->access_list)
+ free (odistance->access_list);
+ ospf6_distance_free (odistance);
+
+ rn->info = NULL;
+ route_unlock_node (rn);
+ route_unlock_node (rn);
+
+ return CMD_SUCCESS;
+}
+
+void
+ospf6_distance_reset (struct ospf6 *o)
+{
+ struct route_node *rn;
+ struct ospf6_distance *odistance;
+
+ for (rn = route_top (o->distance_table); rn; rn = route_next (rn))
+ if ((odistance = rn->info) != NULL)
+ {
+ if (odistance->access_list)
+ free (odistance->access_list);
+ ospf6_distance_free (odistance);
+ rn->info = NULL;
+ route_unlock_node (rn);
+ }
+}
+
+u_char
+ospf6_distance_apply (struct prefix_ipv6 *p, struct ospf6_route *or)
+{
+ struct ospf6 *o;
+
+ o = ospf6;
+ if (o == NULL)
+ return 0;
+
+ if (o->distance_intra)
+ if (or->path.type == OSPF6_PATH_TYPE_INTRA)
+ return o->distance_intra;
+
+ if (o->distance_inter)
+ if (or->path.type == OSPF6_PATH_TYPE_INTER)
+ return o->distance_inter;
+
+ if (o->distance_external)
+ if(or->path.type == OSPF6_PATH_TYPE_EXTERNAL1
+ || or->path.type == OSPF6_PATH_TYPE_EXTERNAL2)
+ return o->distance_external;
+
+ if (o->distance_all)
+ return o->distance_all;
+
+ return 0;
+}
+
static void
ospf6_zebra_connected (struct zclient *zclient)
{