summaryrefslogtreecommitdiffstats
path: root/ospf6d
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 04:24:34 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 04:24:34 +0000
commit137ce8dd46d313f15ee93ddbb5428d702aa61ed8 (patch)
treea49f76849019651842962dff2197b705e33831e7 /ospf6d
parentReleasing progress-linux version 9.1-0.1~progress7.99u1. (diff)
downloadfrr-137ce8dd46d313f15ee93ddbb5428d702aa61ed8.tar.xz
frr-137ce8dd46d313f15ee93ddbb5428d702aa61ed8.zip
Merging upstream version 10.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ospf6d')
-rw-r--r--ospf6d/ospf6_area.c4
-rw-r--r--ospf6d/ospf6_asbr.c7
-rw-r--r--ospf6d/ospf6_auth_trailer.c125
-rw-r--r--ospf6d/ospf6_auth_trailer.h9
-rw-r--r--ospf6d/ospf6_gr.c27
-rw-r--r--ospf6d/ospf6_interface.c871
-rw-r--r--ospf6d/ospf6_interface.h54
-rw-r--r--ospf6d/ospf6_intra.c6
-rw-r--r--ospf6d/ospf6_main.c44
-rw-r--r--ospf6d/ospf6_message.c103
-rw-r--r--ospf6d/ospf6_message.h5
-rw-r--r--ospf6d/ospf6_neighbor.c567
-rw-r--r--ospf6d/ospf6_neighbor.h20
-rw-r--r--ospf6d/ospf6_route.c6
-rw-r--r--ospf6d/ospf6_route.h2
-rw-r--r--ospf6d/ospf6_snmp.c7
-rw-r--r--ospf6d/ospf6_top.c170
-rw-r--r--ospf6d/ospf6_top.h2
-rw-r--r--ospf6d/ospf6_zebra.c28
-rw-r--r--ospf6d/subdir.am2
20 files changed, 1175 insertions, 884 deletions
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index 69c711b..cf5479e 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -731,7 +731,7 @@ void ospf6_area_config_write(struct vty *vty, struct ospf6 *ospf6)
DEFUN (area_filter_list,
area_filter_list_cmd,
- "area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST_NAME <in|out>",
+ "area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST6_NAME <in|out>",
"OSPF6 area parameters\n"
"OSPF6 area ID in IP address format\n"
"OSPF6 area ID as a decimal value\n"
@@ -774,7 +774,7 @@ DEFUN (area_filter_list,
DEFUN (no_area_filter_list,
no_area_filter_list_cmd,
- "no area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST_NAME <in|out>",
+ "no area <A.B.C.D|(0-4294967295)> filter-list prefix PREFIXLIST6_NAME <in|out>",
NO_STR
"OSPF6 area parameters\n"
"OSPF6 area ID in IP address format\n"
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index 99c3e16..d1c2b8b 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -481,7 +481,7 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
static int ospf6_ase_forward_address_check(struct ospf6 *ospf6,
struct in6_addr *fwd_addr)
{
- struct listnode *anode, *node, *cnode;
+ struct listnode *anode, *node;
struct ospf6_interface *oi;
struct ospf6_area *oa;
struct interface *ifp;
@@ -494,7 +494,7 @@ static int ospf6_ase_forward_address_check(struct ospf6 *ospf6,
continue;
ifp = oi->interface;
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
+ frr_each (if_connected, ifp->connected, c) {
if (IPV6_ADDR_SAME(&c->address->u.prefix6,
fwd_addr))
return 0;
@@ -1407,12 +1407,11 @@ static void ospf6_external_lsa_fwd_addr_set(struct ospf6 *ospf6,
FOR_ALL_INTERFACES (vrf, ifp) {
struct ospf6_interface *oi = ifp->info;
struct connected *connected;
- struct listnode *node;
if (!oi || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
continue;
- FOR_ALL_INTERFACES_ADDRESSES (ifp, connected, node) {
+ frr_each (if_connected, ifp->connected, connected) {
if (connected->address->family != AF_INET6)
continue;
if (IN6_IS_ADDR_LINKLOCAL(&connected->address->u.prefix6))
diff --git a/ospf6d/ospf6_auth_trailer.c b/ospf6d/ospf6_auth_trailer.c
index 10e0092..8d9eff4 100644
--- a/ospf6d/ospf6_auth_trailer.c
+++ b/ospf6d/ospf6_auth_trailer.c
@@ -4,6 +4,13 @@
*/
#include "zebra.h"
+#include <sys/stat.h>
+
+#ifdef CRYPTO_OPENSSL
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#endif
+
#include "config.h"
#include "memory.h"
#include "ospf6d.h"
@@ -23,9 +30,13 @@
#include "ospf6_zebra.h"
#include "lib/keychain.h"
+#define OSPF6D_COMPAT_AUTHSEQ_NAME "%s/ospf6d-at-seq-no.dat", frr_runstatedir
+
unsigned char conf_debug_ospf6_auth[2];
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_AUTH_HASH_XOR, "OSPF6 auth hash xor");
+static void ospf6_auth_seqno_nvm_update(struct ospf6 *ospf6);
+
/*Apad is the hexadecimal value 0x878FE1F3. */
const uint8_t ospf6_hash_apad_max[KEYCHAIN_MAX_HASH_SIZE] = {
0x87, 0x8f, 0xe1, 0xf3, 0x87, 0x8f, 0xe1, 0xf3, 0x87, 0x8f, 0xe1,
@@ -855,23 +866,11 @@ void install_element_ospf6_clear_intf_auth(void)
install_element(ENABLE_NODE, &clear_ipv6_ospf6_intf_auth_cmd);
}
-enum ospf6_auth_err ospf6_auth_nvm_file_exist(void)
-{
- struct stat buffer;
- int exist;
-
- exist = stat(OSPF6_AUTH_SEQ_NUM_FILE, &buffer);
- if (exist == 0)
- return OSPF6_AUTH_FILE_EXIST;
- else
- return OSPF6_AUTH_FILE_DO_NOT_EXIST;
-}
-
/*
* Record in non-volatile memory the given ospf6 process,
* authentication trailer higher order sequence number.
*/
-void ospf6_auth_seqno_nvm_update(struct ospf6 *ospf6)
+static void ospf6_auth_seqno_nvm_update(struct ospf6 *ospf6)
{
const char *inst_name;
json_object *json;
@@ -883,9 +882,7 @@ void ospf6_auth_seqno_nvm_update(struct ospf6 *ospf6)
inst_name = ospf6->name ? ospf6->name : VRF_DEFAULT_NAME;
- json = json_object_from_file((char *)OSPF6_AUTH_SEQ_NUM_FILE);
- if (json == NULL)
- json = json_object_new_object();
+ json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@@ -905,49 +902,82 @@ void ospf6_auth_seqno_nvm_update(struct ospf6 *ospf6)
*/
json_object_int_add(json_instance, "sequence_number", ospf6->seqnum_h);
- json_object_to_file_ext((char *)OSPF6_AUTH_SEQ_NUM_FILE, json,
- JSON_C_TO_STRING_PRETTY);
- json_object_free(json);
+ frr_daemon_state_save(&json);
}
/*
* Delete authentication sequence number for a given OSPF6 process
* from non-volatile memory.
*/
-void ospf6_auth_seqno_nvm_delete(struct ospf6 *ospf6)
+__attribute__((unused)) static void
+ospf6_auth_seqno_nvm_delete(struct ospf6 *ospf6)
{
const char *inst_name;
json_object *json;
json_object *json_instances;
+ json_object *json_instance;
zlog_err("Higher order sequence number delete for %s process",
ospf6->name);
inst_name = ospf6->name ? ospf6->name : VRF_DEFAULT_NAME;
- json = json_object_from_file((char *)OSPF6_AUTH_SEQ_NUM_FILE);
- if (json == NULL)
- json = json_object_new_object();
+ json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
- json_instances = json_object_new_object();
- json_object_object_add(json, "instances", json_instances);
+ json_object_put(json);
+ return;
+ }
+
+ json_object_object_get_ex(json_instances, inst_name, &json_instance);
+ if (json_instance) {
+ json_object_put(json);
+ return;
}
- json_object_object_del(json_instances, inst_name);
+ json_object_object_del(json_instance, "sequence_number");
- json_object_to_file_ext((char *)OSPF6_AUTH_SEQ_NUM_FILE, json,
- JSON_C_TO_STRING_PRETTY);
- json_object_free(json);
+ frr_daemon_state_save(&json);
}
+static struct json_object *ospf6_auth_seqno_compat_read(const char *inst_name)
+{
+ /* try legacy location */
+ char compat_path[512];
+ json_object *json;
+ json_object *json_instances = NULL;
+ json_object *json_instance = NULL;
+ json_object *json_seqnum = NULL;
+
+ snprintf(compat_path, sizeof(compat_path), OSPF6D_COMPAT_AUTHSEQ_NAME);
+ json = json_object_from_file(compat_path);
+
+ if (json)
+ json_object_object_get_ex(json, "instances", &json_instances);
+ if (json_instances)
+ json_object_object_get_ex(json_instances, inst_name,
+ &json_instance);
+ if (json_instance)
+ json_object_object_get_ex(json_instance, "sequence_number",
+ &json_seqnum);
+ if (json_seqnum)
+ /* => free the file-level object and still return this */
+ json_seqnum = json_object_get(json_seqnum);
+
+ if (json) {
+ json_object_free(json);
+ unlink(compat_path);
+ }
+ return json_seqnum;
+}
+
/*
* Fetch from non-volatile memory the stored ospf6 process
* authentication sequence number.
*/
-void ospf6_auth_seqno_nvm_read(struct ospf6 *ospf6)
+static void ospf6_auth_seqno_nvm_read(struct ospf6 *ospf6)
{
const char *inst_name;
json_object *json;
@@ -957,9 +987,7 @@ void ospf6_auth_seqno_nvm_read(struct ospf6 *ospf6)
inst_name = ospf6->name ? ospf6->name : VRF_DEFAULT_NAME;
- json = json_object_from_file((char *)OSPF6_AUTH_SEQ_NUM_FILE);
- if (json == NULL)
- json = json_object_new_object();
+ json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@@ -976,13 +1004,34 @@ void ospf6_auth_seqno_nvm_read(struct ospf6 *ospf6)
json_object_object_get_ex(json_instance, "sequence_number",
&json_seqnum);
- ospf6->seqnum_h = json_object_get_int(json_seqnum);
+
+ if (json_seqnum)
+ /* cf. reference taken in compat_read above */
+ json_seqnum = json_object_get(json_seqnum);
+ else
+ json_seqnum = ospf6_auth_seqno_compat_read(inst_name);
+
+ ospf6->seqnum_l = 0;
+ if (json_seqnum) {
+ ospf6->seqnum_h = json_object_get_int(json_seqnum);
+ ospf6->seqnum_h += 1;
+ } else {
+ ospf6->seqnum_h = 0;
+ }
+
+ if (json_seqnum)
+ json_object_put(json_seqnum);
zlog_err("Higher order sequence number %d read for %s process %s",
ospf6->seqnum_h, ospf6->name, strerror(errno));
- json_object_object_del(json_instances, inst_name);
- json_object_to_file_ext((char *)OSPF6_AUTH_SEQ_NUM_FILE, json,
- JSON_C_TO_STRING_PRETTY);
- json_object_free(json);
+ json_object_object_del(json_instance, "sequence_number");
+
+ frr_daemon_state_save(&json);
+}
+
+void ospf6_auth_init(struct ospf6 *o)
+{
+ ospf6_auth_seqno_nvm_read(o);
+ ospf6_auth_seqno_nvm_update(o);
}
diff --git a/ospf6d/ospf6_auth_trailer.h b/ospf6d/ospf6_auth_trailer.h
index 3f82a7b..9073ae4 100644
--- a/ospf6d/ospf6_auth_trailer.h
+++ b/ospf6d/ospf6_auth_trailer.h
@@ -48,10 +48,10 @@ enum ospf6_auth_err {
OSPF6_AUTH_VALIDATE_SUCCESS = 0,
OSPF6_AUTH_VALIDATE_FAILURE,
OSPF6_AUTH_PROCESS_NORMAL,
- OSPF6_AUTH_FILE_EXIST,
- OSPF6_AUTH_FILE_DO_NOT_EXIST
};
+void ospf6_auth_init(struct ospf6 *o);
+
void ospf6_auth_hdr_dump_send(struct ospf6_header *ospfh, uint16_t length);
void ospf6_auth_hdr_dump_recv(struct ospf6_header *ospfh, uint16_t length,
unsigned int lls_len);
@@ -73,8 +73,5 @@ void ospf6_auth_digest_send(struct in6_addr *src, struct ospf6_interface *oi,
void install_element_ospf6_debug_auth(void);
int config_write_ospf6_debug_auth(struct vty *vty);
void install_element_ospf6_clear_intf_auth(void);
-enum ospf6_auth_err ospf6_auth_nvm_file_exist(void);
-void ospf6_auth_seqno_nvm_update(struct ospf6 *ospf6);
-void ospf6_auth_seqno_nvm_delete(struct ospf6 *ospf6);
-void ospf6_auth_seqno_nvm_read(struct ospf6 *ospf6);
+
#endif /* __OSPF6_AUTH_TRAILER_H__ */
diff --git a/ospf6d/ospf6_gr.c b/ospf6d/ospf6_gr.c
index 69230e5..34cb970 100644
--- a/ospf6d/ospf6_gr.c
+++ b/ospf6d/ospf6_gr.c
@@ -561,9 +561,7 @@ static void ospf6_gr_nvm_update(struct ospf6 *ospf6, bool prepare)
inst_name = ospf6->name ? ospf6->name : VRF_DEFAULT_NAME;
- json = json_object_from_file((char *)OSPF6D_GR_STATE);
- if (json == NULL)
- json = json_object_new_object();
+ json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@@ -591,9 +589,7 @@ static void ospf6_gr_nvm_update(struct ospf6 *ospf6, bool prepare)
json_object_int_add(json_instance, "timestamp",
time(NULL) + ospf6->gr_info.grace_period);
- json_object_to_file_ext((char *)OSPF6D_GR_STATE, json,
- JSON_C_TO_STRING_PRETTY);
- json_object_free(json);
+ frr_daemon_state_save(&json);
}
/*
@@ -608,9 +604,7 @@ void ospf6_gr_nvm_delete(struct ospf6 *ospf6)
inst_name = ospf6->name ? ospf6->name : VRF_DEFAULT_NAME;
- json = json_object_from_file((char *)OSPF6D_GR_STATE);
- if (json == NULL)
- json = json_object_new_object();
+ json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@@ -620,9 +614,7 @@ void ospf6_gr_nvm_delete(struct ospf6 *ospf6)
json_object_object_del(json_instances, inst_name);
- json_object_to_file_ext((char *)OSPF6D_GR_STATE, json,
- JSON_C_TO_STRING_PRETTY);
- json_object_free(json);
+ frr_daemon_state_save(&json);
}
/*
@@ -641,9 +633,7 @@ void ospf6_gr_nvm_read(struct ospf6 *ospf6)
inst_name = ospf6->name ? ospf6->name : VRF_DEFAULT_NAME;
- json = json_object_from_file((char *)OSPF6D_GR_STATE);
- if (json == NULL)
- json = json_object_new_object();
+ json = frr_daemon_state_load();
json_object_object_get_ex(json, "instances", &json_instances);
if (!json_instances) {
@@ -687,11 +677,10 @@ void ospf6_gr_nvm_read(struct ospf6 *ospf6)
ospf6->gr_info.grace_period);
}
- json_object_object_del(json_instances, inst_name);
+ json_object_object_del(json_instance, "gracePeriod");
+ json_object_object_del(json_instance, "timestamp");
- json_object_to_file_ext((char *)OSPF6D_GR_STATE, json,
- JSON_C_TO_STRING_PRETTY);
- json_object_free(json);
+ frr_daemon_state_save(&json);
}
void ospf6_gr_unplanned_start_interface(struct ospf6_interface *oi)
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index a79f993..b9dace2 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -49,8 +49,9 @@ DEFINE_HOOK(ospf6_interface_change,
unsigned char conf_debug_ospf6_interface = 0;
const char *const ospf6_interface_state_str[] = {
- "None", "Down", "Loopback", "Waiting", "PointToPoint",
- "DROther", "BDR", "DR", NULL};
+ "None", "Down", "Loopback", "Waiting", "PointToPoint",
+ "PtMultipoint", "DROther", "BDR", "DR", NULL
+};
int ospf6_interface_neighbor_count(struct ospf6_interface *oi)
{
@@ -83,8 +84,7 @@ struct ospf6_interface *ospf6_interface_lookup_by_ifindex(ifindex_t ifindex,
}
/* schedule routing table recalculation */
-static void ospf6_interface_lsdb_hook(struct ospf6_lsa *lsa,
- unsigned int reason)
+static void ospf6_interface_lsdb_hook(struct ospf6_lsa *lsa, unsigned int reason)
{
struct ospf6_interface *oi;
@@ -227,9 +227,8 @@ struct ospf6_interface *ospf6_interface_create(struct interface *ifp)
iobuflen = ospf6_iobuf_size(ifp->mtu6);
if (oi->ifmtu > iobuflen) {
if (IS_OSPF6_DEBUG_INTERFACE)
- zlog_debug(
- "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
- ifp->name, iobuflen);
+ zlog_debug("Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
+ ifp->name, iobuflen);
oi->ifmtu = iobuflen;
}
@@ -242,8 +241,8 @@ struct ospf6_interface *ospf6_interface_create(struct interface *ifp)
oi->lsdb->hook_remove = ospf6_interface_lsdb_hook_remove;
oi->lsdb_self = ospf6_lsdb_create(oi);
- oi->route_connected =
- OSPF6_ROUTE_TABLE_CREATE(INTERFACE, CONNECTED_ROUTES);
+ oi->route_connected = OSPF6_ROUTE_TABLE_CREATE(INTERFACE,
+ CONNECTED_ROUTES);
oi->route_connected->scope = oi;
/* link both */
@@ -344,12 +343,11 @@ void ospf6_interface_disable(struct ospf6_interface *oi)
static struct in6_addr *
ospf6_interface_get_linklocal_address(struct interface *ifp)
{
- struct listnode *n;
struct connected *c;
struct in6_addr *l = (struct in6_addr *)NULL;
/* for each connected address */
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
+ frr_each (if_connected, ifp->connected, c) {
/* if family not AF_INET6, ignore */
if (c->address->family != AF_INET6)
continue;
@@ -380,23 +378,21 @@ void ospf6_interface_state_update(struct interface *ifp)
iobuflen = ospf6_iobuf_size(ifp->mtu6);
if (oi->ifmtu > iobuflen) {
if (IS_OSPF6_DEBUG_INTERFACE)
- zlog_debug(
- "Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
- ifp->name, iobuflen);
+ zlog_debug("Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
+ ifp->name, iobuflen);
oi->ifmtu = iobuflen;
}
} else if (oi->c_ifmtu > ifp->mtu6) {
oi->ifmtu = ifp->mtu6;
- zlog_warn(
- "Configured mtu %u on %s overridden by kernel %u",
- oi->c_ifmtu, ifp->name, ifp->mtu6);
+ zlog_warn("Configured mtu %u on %s overridden by kernel %u",
+ oi->c_ifmtu, ifp->name, ifp->mtu6);
} else
oi->ifmtu = oi->c_ifmtu;
}
- if (if_is_operative(ifp)
- && (ospf6_interface_get_linklocal_address(oi->interface)
- || if_is_loopback(oi->interface)))
+ if (if_is_operative(ifp) &&
+ (ospf6_interface_get_linklocal_address(oi->interface) ||
+ if_is_loopback(oi->interface)))
event_execute(master, interface_up, oi, 0, NULL);
else
event_execute(master, interface_down, oi, 0, NULL);
@@ -407,9 +403,7 @@ void ospf6_interface_state_update(struct interface *ifp)
void ospf6_interface_connected_route_update(struct interface *ifp)
{
struct ospf6_interface *oi;
- struct ospf6_route *route;
struct connected *c;
- struct listnode *node, *nnode;
struct in6_addr nh_addr;
oi = (struct ospf6_interface *)ifp->info;
@@ -429,7 +423,7 @@ void ospf6_interface_connected_route_update(struct interface *ifp)
/* update "route to advertise" interface route table */
ospf6_route_remove_all(oi->route_connected);
- for (ALL_LIST_ELEMENTS(oi->interface->connected, node, nnode, c)) {
+ frr_each (if_connected, ifp->connected, c) {
if (c->address->family != AF_INET6)
continue;
@@ -453,14 +447,43 @@ void ospf6_interface_connected_route_update(struct interface *ifp)
ret = prefix_list_apply(plist, (void *)c->address);
if (ret == PREFIX_DENY) {
if (IS_OSPF6_DEBUG_INTERFACE)
- zlog_debug(
- "%pFX on %s filtered by prefix-list %s ",
- c->address, oi->interface->name,
- oi->plist_name);
+ zlog_debug("%pFX on %s filtered by prefix-list %s ",
+ c->address,
+ oi->interface->name,
+ oi->plist_name);
continue;
}
}
+ if (oi->state == OSPF6_INTERFACE_LOOPBACK ||
+ oi->state == OSPF6_INTERFACE_POINTTOMULTIPOINT ||
+ oi->state == OSPF6_INTERFACE_POINTTOPOINT) {
+ struct ospf6_route *la_route;
+
+ la_route = ospf6_route_create(oi->area->ospf6);
+ la_route->prefix = *c->address;
+ la_route->prefix.prefixlen = 128;
+ la_route->prefix_options |= OSPF6_PREFIX_OPTION_LA;
+
+ la_route->type = OSPF6_DEST_TYPE_NETWORK;
+ la_route->path.area_id = oi->area->area_id;
+ la_route->path.type = OSPF6_PATH_TYPE_INTRA;
+ la_route->path.cost = 0;
+ inet_pton(AF_INET6, "::1", &nh_addr);
+ ospf6_route_add_nexthop(la_route, oi->interface->ifindex,
+ &nh_addr);
+ ospf6_route_add(la_route, oi->route_connected);
+ }
+
+ if (oi->state == OSPF6_INTERFACE_POINTTOMULTIPOINT &&
+ !oi->p2xp_connected_pfx_include)
+ continue;
+ if (oi->state == OSPF6_INTERFACE_POINTTOPOINT &&
+ oi->p2xp_connected_pfx_exclude)
+ continue;
+
+ struct ospf6_route *route;
+
route = ospf6_route_create(oi->area->ospf6);
memcpy(&route->prefix, c->address, sizeof(struct prefix));
apply_mask(&route->prefix);
@@ -469,8 +492,7 @@ void ospf6_interface_connected_route_update(struct interface *ifp)
route->path.type = OSPF6_PATH_TYPE_INTRA;
route->path.cost = oi->cost;
inet_pton(AF_INET6, "::1", &nh_addr);
- ospf6_route_add_nexthop(route, oi->interface->ifindex,
- &nh_addr);
+ ospf6_route_add_nexthop(route, oi->interface->ifindex, &nh_addr);
ospf6_route_add(route, oi->route_connected);
}
@@ -506,17 +528,17 @@ static int ospf6_interface_state_change(uint8_t next_state,
ospf6 = oi->area->ospf6;
- if ((prev_state == OSPF6_INTERFACE_DR
- || prev_state == OSPF6_INTERFACE_BDR)
- && (next_state != OSPF6_INTERFACE_DR
- && next_state != OSPF6_INTERFACE_BDR))
+ if ((prev_state == OSPF6_INTERFACE_DR ||
+ prev_state == OSPF6_INTERFACE_BDR) &&
+ (next_state != OSPF6_INTERFACE_DR &&
+ next_state != OSPF6_INTERFACE_BDR))
ospf6_sso(oi->interface->ifindex, &alldrouters6,
IPV6_LEAVE_GROUP, ospf6->fd);
- if ((prev_state != OSPF6_INTERFACE_DR
- && prev_state != OSPF6_INTERFACE_BDR)
- && (next_state == OSPF6_INTERFACE_DR
- || next_state == OSPF6_INTERFACE_BDR))
+ if ((prev_state != OSPF6_INTERFACE_DR &&
+ prev_state != OSPF6_INTERFACE_BDR) &&
+ (next_state == OSPF6_INTERFACE_DR ||
+ next_state == OSPF6_INTERFACE_BDR))
ospf6_sso(oi->interface->ifindex, &alldrouters6,
IPV6_JOIN_GROUP, ospf6->fd);
@@ -526,13 +548,17 @@ static int ospf6_interface_state_change(uint8_t next_state,
OSPF6_NETWORK_LSA_EXECUTE(oi);
OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi);
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
- } else if (prev_state == OSPF6_INTERFACE_DR
- || next_state == OSPF6_INTERFACE_DR) {
+ } else if (prev_state == OSPF6_INTERFACE_DR ||
+ next_state == OSPF6_INTERFACE_DR) {
OSPF6_NETWORK_LSA_SCHEDULE(oi);
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi);
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
}
+ if (next_state == OSPF6_INTERFACE_POINTTOPOINT ||
+ next_state == OSPF6_INTERFACE_POINTTOMULTIPOINT)
+ ospf6_if_p2xp_up(oi);
+
hook_call(ospf6_interface_change, oi, next_state, prev_state);
return 0;
@@ -547,8 +573,8 @@ static int ospf6_interface_state_change(uint8_t next_state,
static struct ospf6_neighbor *better_bdrouter(struct ospf6_neighbor *a,
struct ospf6_neighbor *b)
{
- if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id)
- && (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id))
+ if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id) &&
+ (b == NULL || !IS_ELIGIBLE(b) || b->drouter == b->router_id))
return NULL;
else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter == a->router_id)
return b;
@@ -577,8 +603,8 @@ static struct ospf6_neighbor *better_bdrouter(struct ospf6_neighbor *a,
static struct ospf6_neighbor *better_drouter(struct ospf6_neighbor *a,
struct ospf6_neighbor *b)
{
- if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id)
- && (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id))
+ if ((a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id) &&
+ (b == NULL || !IS_ELIGIBLE(b) || b->drouter != b->router_id))
return NULL;
else if (a == NULL || !IS_ELIGIBLE(a) || a->drouter != a->router_id)
return b;
@@ -641,10 +667,10 @@ uint8_t dr_election(struct ospf6_interface *oi)
drouter = bdrouter;
/* the router itself is newly/no longer DR/BDR (4) */
- if ((drouter == &myself && myself.drouter != myself.router_id)
- || (drouter != &myself && myself.drouter == myself.router_id)
- || (bdrouter == &myself && myself.bdrouter != myself.router_id)
- || (bdrouter != &myself && myself.bdrouter == myself.router_id)) {
+ if ((drouter == &myself && myself.drouter != myself.router_id) ||
+ (drouter != &myself && myself.drouter == myself.router_id) ||
+ (bdrouter == &myself && myself.bdrouter != myself.router_id) ||
+ (bdrouter != &myself && myself.bdrouter == myself.router_id)) {
myself.drouter = (drouter ? drouter->router_id : htonl(0));
myself.bdrouter = (bdrouter ? bdrouter->router_id : htonl(0));
@@ -718,8 +744,8 @@ static bool ifmaddr_check(ifindex_t ifindex, struct in6_addr *addr)
continue;
sdl = (struct sockaddr_dl *)ifma->ifma_name;
sin6 = (struct sockaddr_in6 *)ifma->ifma_addr;
- if (sdl->sdl_index == ifindex
- && memcmp(&sin6->sin6_addr, addr, IPV6_MAX_BYTELEN) == 0) {
+ if (sdl->sdl_index == ifindex &&
+ memcmp(&sin6->sin6_addr, addr, IPV6_MAX_BYTELEN) == 0) {
found = true;
break;
}
@@ -759,11 +785,10 @@ void interface_up(struct event *thread)
}
/* check interface has a link-local address */
- if (!(ospf6_interface_get_linklocal_address(oi->interface)
- || if_is_loopback(oi->interface))) {
- zlog_warn(
- "Interface %s has no link local address, can't execute [InterfaceUp]",
- oi->interface->name);
+ if (!(ospf6_interface_get_linklocal_address(oi->interface) ||
+ if_is_loopback(oi->interface))) {
+ zlog_warn("Interface %s has no link local address, can't execute [InterfaceUp]",
+ oi->interface->name);
return;
}
@@ -780,9 +805,8 @@ void interface_up(struct event *thread)
/* If no area assigned, return */
if (oi->area == NULL) {
- zlog_warn(
- "%s: Not scheduling Hello for %s as there is no area assigned yet",
- __func__, oi->interface->name);
+ zlog_warn("%s: Not scheduling Hello for %s as there is no area assigned yet",
+ __func__, oi->interface->name);
return;
}
@@ -807,9 +831,8 @@ void interface_up(struct event *thread)
* the interface actually left the group.
*/
if (ifmaddr_check(oi->interface->ifindex, &allspfrouters6)) {
- zlog_info(
- "Interface %s is still in all routers group, rescheduling for SSO",
- oi->interface->name);
+ zlog_info("Interface %s is still in all routers group, rescheduling for SSO",
+ oi->interface->name);
event_add_timer(master, interface_up, oi,
OSPF6_INTERFACE_SSO_RETRY_INT, &oi->thread_sso);
return;
@@ -820,12 +843,10 @@ void interface_up(struct event *thread)
/* Join AllSPFRouters */
if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP,
- ospf6->fd)
- < 0) {
+ ospf6->fd) < 0) {
if (oi->sso_try_cnt++ < OSPF6_INTERFACE_SSO_RETRY_MAX) {
- zlog_info(
- "Scheduling %s for sso retry, trial count: %d",
- oi->interface->name, oi->sso_try_cnt);
+ zlog_info("Scheduling %s for sso retry, trial count: %d",
+ oi->interface->name, oi->sso_try_cnt);
event_add_timer(master, interface_up, oi,
OSPF6_INTERFACE_SSO_RETRY_INT,
&oi->thread_sso);
@@ -838,8 +859,8 @@ void interface_up(struct event *thread)
ospf6_interface_connected_route_update(oi->interface);
/* Schedule Hello */
- if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE)
- && !if_is_loopback(oi->interface)) {
+ if (!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE) &&
+ !if_is_loopback(oi->interface)) {
event_add_timer(master, ospf6_hello_send, oi, 0,
&oi->thread_send_hello);
}
@@ -849,6 +870,9 @@ void interface_up(struct event *thread)
ospf6_interface_state_change(OSPF6_INTERFACE_LOOPBACK, oi);
} else if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT, oi);
+ } else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) {
+ ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOMULTIPOINT,
+ oi);
} else if (oi->priority == 0)
ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER, oi);
else {
@@ -899,9 +923,8 @@ void neighbor_change(struct event *thread)
zlog_debug("Interface Event %s: [NeighborChange]",
oi->interface->name);
- if (oi->state == OSPF6_INTERFACE_DROTHER
- || oi->state == OSPF6_INTERFACE_BDR
- || oi->state == OSPF6_INTERFACE_DR)
+ if (oi->state == OSPF6_INTERFACE_DROTHER ||
+ oi->state == OSPF6_INTERFACE_BDR || oi->state == OSPF6_INTERFACE_DR)
ospf6_interface_state_change(dr_election(oi), oi);
}
@@ -977,6 +1000,8 @@ static const char *ospf6_iftype_str(uint8_t iftype)
return "BROADCAST";
case OSPF_IFTYPE_POINTOPOINT:
return "POINTOPOINT";
+ case OSPF_IFTYPE_POINTOMULTIPOINT:
+ return "POINTOMULTIPOINT";
}
return "UNKNOWN";
}
@@ -988,7 +1013,6 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
struct ospf6_interface *oi;
struct connected *c;
struct prefix *p;
- struct listnode *i;
char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32];
uint8_t default_iftype;
struct timeval res, now;
@@ -1035,7 +1059,7 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
if (use_json) {
json_arr = json_object_new_array();
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
+ frr_each (if_connected, ifp->connected, c) {
json_addr = json_object_new_object();
p = c->address;
prefix2str(p, strbuf, sizeof(strbuf));
@@ -1067,7 +1091,7 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
} else {
vty_out(vty, " Internet Address:\n");
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
+ frr_each (if_connected, ifp->connected, c) {
p = c->address;
prefix2str(p, strbuf, sizeof(strbuf));
switch (p->family) {
@@ -1086,12 +1110,10 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
if (use_json) {
if (oi->area) {
- json_object_boolean_true_add(json_obj,
- "attachedToArea");
+ json_object_boolean_true_add(json_obj, "attachedToArea");
json_object_int_add(json_obj, "instanceId",
oi->instance_id);
- json_object_int_add(json_obj, "interfaceMtu",
- oi->ifmtu);
+ json_object_int_add(json_obj, "interfaceMtu", oi->ifmtu);
json_object_int_add(json_obj, "autoDetect", ifp->mtu6);
json_object_string_add(json_obj, "mtuMismatchDetection",
oi->mtu_ignore ? "disabled"
@@ -1131,9 +1153,9 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
oi->dead_interval);
json_object_int_add(json_obj, "timerIntervalsConfigRetransmit",
oi->rxmt_interval);
- json_object_boolean_add(
- json_obj, "timerPassiveIface",
- !!CHECK_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE));
+ json_object_boolean_add(json_obj, "timerPassiveIface",
+ !!CHECK_FLAG(oi->flag,
+ OSPF6_INTERFACE_PASSIVE));
} else {
vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n",
ospf6_interface_state_str[oi->state], oi->transdelay,
@@ -1166,24 +1188,23 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
if (use_json) {
timerclear(&res);
if (event_is_scheduled(oi->thread_send_lsupdate))
- timersub(&oi->thread_send_lsupdate->u.sands, &now,
- &res);
+ timersub(&oi->thread_send_lsupdate->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
json_object_int_add(json_obj, "pendingLsaLsUpdateCount",
oi->lsupdate_list->count);
json_object_string_add(json_obj, "pendingLsaLsUpdateTime",
duration);
- json_object_string_add(
- json_obj, "lsUpdateSendThread",
- (event_is_scheduled(oi->thread_send_lsupdate) ? "on"
- : "off"));
+ json_object_string_add(json_obj, "lsUpdateSendThread",
+ (event_is_scheduled(
+ oi->thread_send_lsupdate)
+ ? "on"
+ : "off"));
json_arr = json_object_new_array();
for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
- json_object_array_add(
- json_arr, json_object_new_string(lsa->name));
- json_object_object_add(json_obj, "pendingLsaLsUpdate",
- json_arr);
+ json_object_array_add(json_arr,
+ json_object_new_string(lsa->name));
+ json_object_object_add(json_obj, "pendingLsaLsUpdate", json_arr);
timerclear(&res);
if (event_is_scheduled(oi->thread_send_lsack))
@@ -1194,15 +1215,15 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
oi->lsack_list->count);
json_object_string_add(json_obj, "pendingLsaLsAckTime",
duration);
- json_object_string_add(
- json_obj, "lsAckSendThread",
- (event_is_scheduled(oi->thread_send_lsack) ? "on"
- : "off"));
+ json_object_string_add(json_obj, "lsAckSendThread",
+ (event_is_scheduled(oi->thread_send_lsack)
+ ? "on"
+ : "off"));
json_arr = json_object_new_array();
for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
- json_object_array_add(
- json_arr, json_object_new_string(lsa->name));
+ json_object_array_add(json_arr,
+ json_object_new_string(lsa->name));
json_object_object_add(json_obj, "pendingLsaLsAck", json_arr);
if (oi->gr.hello_delay.interval != 0)
@@ -1211,8 +1232,7 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
} else {
timerclear(&res);
if (event_is_scheduled(oi->thread_send_lsupdate))
- timersub(&oi->thread_send_lsupdate->u.sands, &now,
- &res);
+ timersub(&oi->thread_send_lsupdate->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
vty_out(vty,
" %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
@@ -1244,9 +1264,8 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
if (use_json) {
struct json_object *json_bfd = json_object_new_object();
- json_object_int_add(
- json_bfd, "detectMultiplier",
- oi->bfd_config.detection_multiplier);
+ json_object_int_add(json_bfd, "detectMultiplier",
+ oi->bfd_config.detection_multiplier);
json_object_int_add(json_bfd, "rxMinInterval",
oi->bfd_config.min_rx);
json_object_int_add(json_bfd, "txMinInterval",
@@ -1269,8 +1288,7 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
OSPF6_AUTH_TRAILER_KEYCHAIN)) {
json_object_string_add(json_auth, "authType",
"keychain");
- json_object_string_add(json_auth,
- "keychainName",
+ json_object_string_add(json_auth, "keychainName",
oi->at_data.keychain);
} else if (CHECK_FLAG(oi->at_data.flags,
OSPF6_AUTH_TRAILER_MANUAL_KEY))
@@ -1310,11 +1328,10 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
/* Find the global address to be used as a forwarding address in NSSA LSA.*/
struct in6_addr *ospf6_interface_get_global_address(struct interface *ifp)
{
- struct listnode *n;
struct connected *c;
/* for each connected address */
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
+ frr_each (if_connected, ifp->connected, c) {
/* if family not AF_INET6, ignore */
if (c->address->family != AF_INET6)
continue;
@@ -1332,7 +1349,6 @@ static int show_ospf6_interface_common(struct vty *vty, vrf_id_t vrf_id,
int idx_ifname, int intf_idx,
int json_idx, bool uj)
{
-
struct vrf *vrf = vrf_lookup_by_id(vrf_id);
struct interface *ifp;
json_object *json;
@@ -1462,18 +1478,15 @@ static int ospf6_interface_show_traffic(struct vty *vty,
json_object_int_add(json_interface, "lsReqTx",
oi->ls_req_out);
json_object_int_add(json_interface,
- "lsUpdateRx",
- oi->ls_upd_in);
- json_object_int_add(json_interface,
- "lsUpdateTx",
+ "lsUpdateRx", oi->ls_upd_in);
+ json_object_int_add(json_interface, "lsUpdateTx",
oi->ls_upd_out);
json_object_int_add(json_interface, "lsAckRx",
oi->ls_ack_in);
json_object_int_add(json_interface, "lsAckTx",
oi->ls_ack_out);
- json_object_object_add(json,
- oi->interface->name,
+ json_object_object_add(json, oi->interface->name,
json_interface);
} else
vty_out(vty,
@@ -1659,8 +1672,8 @@ DEFUN(show_ipv6_ospf6_interface_ifname_prefix,
}
oi = ifp->info;
- if (oi == NULL
- || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) {
+ if (oi == NULL ||
+ CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) {
vty_out(vty,
"Interface %s not attached to area\n",
argv[idx_ifname]->arg);
@@ -1687,8 +1700,7 @@ DEFUN(show_ipv6_ospf6_interface_prefix, show_ipv6_ospf6_interface_prefix_cmd,
|<X:X::X:X|X:X::X:X/M> [<match|detail>]\
>] [json]",
SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
- "All VRFs\n" INTERFACE_STR
- "Display connected prefixes to advertise\n"
+ "All VRFs\n" INTERFACE_STR "Display connected prefixes to advertise\n"
"Display details of the prefixes\n" OSPF6_ROUTE_ADDRESS_STR
OSPF6_ROUTE_PREFIX_STR OSPF6_ROUTE_MATCH_STR
"Display details of the prefixes\n" JSON_STR)
@@ -1713,9 +1725,9 @@ DEFUN(show_ipv6_ospf6_interface_prefix, show_ipv6_ospf6_interface_prefix_cmd,
vrf = vrf_lookup_by_id(ospf6->vrf_id);
FOR_ALL_INTERFACES (vrf, ifp) {
oi = (struct ospf6_interface *)ifp->info;
- if (oi == NULL
- || CHECK_FLAG(oi->flag,
- OSPF6_INTERFACE_DISABLE))
+ if (oi == NULL ||
+ CHECK_FLAG(oi->flag,
+ OSPF6_INTERFACE_DISABLE))
continue;
ospf6_route_table_show(vty, idx_prefix, argc,
@@ -1790,14 +1802,11 @@ void ospf6_interface_stop(struct ospf6_interface *oi)
}
/* interface variable set command */
-DEFUN (ipv6_ospf6_area,
- ipv6_ospf6_area_cmd,
- "ipv6 ospf6 area <A.B.C.D|(0-4294967295)>",
- IP6_STR
- OSPF6_STR
- "Specify the OSPF6 area ID\n"
- "OSPF6 area ID in IPv4 address notation\n"
- "OSPF6 area ID in decimal notation\n")
+DEFUN(ipv6_ospf6_area, ipv6_ospf6_area_cmd,
+ "ipv6 ospf6 area <A.B.C.D|(0-4294967295)>",
+ IP6_STR OSPF6_STR "Specify the OSPF6 area ID\n"
+ "OSPF6 area ID in IPv4 address notation\n"
+ "OSPF6 area ID in decimal notation\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
@@ -1831,15 +1840,11 @@ DEFUN (ipv6_ospf6_area,
return CMD_SUCCESS;
}
-DEFUN (no_ipv6_ospf6_area,
- no_ipv6_ospf6_area_cmd,
- "no ipv6 ospf6 area [<A.B.C.D|(0-4294967295)>]",
- NO_STR
- IP6_STR
- OSPF6_STR
- "Specify the OSPF6 area ID\n"
- "OSPF6 area ID in IPv4 address notation\n"
- "OSPF6 area ID in decimal notation\n")
+DEFUN(no_ipv6_ospf6_area, no_ipv6_ospf6_area_cmd,
+ "no ipv6 ospf6 area [<A.B.C.D|(0-4294967295)>]",
+ NO_STR IP6_STR OSPF6_STR "Specify the OSPF6 area ID\n"
+ "OSPF6 area ID in IPv4 address notation\n"
+ "OSPF6 area ID in decimal notation\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
@@ -1859,14 +1864,9 @@ DEFUN (no_ipv6_ospf6_area,
return CMD_SUCCESS;
}
-DEFUN (ipv6_ospf6_ifmtu,
- ipv6_ospf6_ifmtu_cmd,
- "ipv6 ospf6 ifmtu (1-65535)",
- IP6_STR
- OSPF6_STR
- "Interface MTU\n"
- "OSPFv3 Interface MTU\n"
- )
+DEFUN(ipv6_ospf6_ifmtu, ipv6_ospf6_ifmtu_cmd, "ipv6 ospf6 ifmtu (1-65535)",
+ IP6_STR OSPF6_STR "Interface MTU\n"
+ "OSPFv3 Interface MTU\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_number = 3;
@@ -1915,15 +1915,10 @@ DEFUN (ipv6_ospf6_ifmtu,
return CMD_SUCCESS;
}
-DEFUN (no_ipv6_ospf6_ifmtu,
- no_ipv6_ospf6_ifmtu_cmd,
- "no ipv6 ospf6 ifmtu [(1-65535)]",
- NO_STR
- IP6_STR
- OSPF6_STR
- "Interface MTU\n"
- "OSPFv3 Interface MTU\n"
- )
+DEFUN(no_ipv6_ospf6_ifmtu, no_ipv6_ospf6_ifmtu_cmd,
+ "no ipv6 ospf6 ifmtu [(1-65535)]",
+ NO_STR IP6_STR OSPF6_STR "Interface MTU\n"
+ "OSPFv3 Interface MTU\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
@@ -1961,13 +1956,9 @@ DEFUN (no_ipv6_ospf6_ifmtu,
return CMD_SUCCESS;
}
-DEFUN (ipv6_ospf6_cost,
- ipv6_ospf6_cost_cmd,
- "ipv6 ospf6 cost (1-65535)",
- IP6_STR
- OSPF6_STR
- "Interface cost\n"
- "Outgoing metric of this interface\n")
+DEFUN(ipv6_ospf6_cost, ipv6_ospf6_cost_cmd, "ipv6 ospf6 cost (1-65535)",
+ IP6_STR OSPF6_STR "Interface cost\n"
+ "Outgoing metric of this interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_number = 3;
@@ -1998,14 +1989,10 @@ DEFUN (ipv6_ospf6_cost,
return CMD_SUCCESS;
}
-DEFUN (no_ipv6_ospf6_cost,
- no_ipv6_ospf6_cost_cmd,
- "no ipv6 ospf6 cost [(1-65535)]",
- NO_STR
- IP6_STR
- OSPF6_STR
- "Calculate interface cost from bandwidth\n"
- "Outgoing metric of this interface\n")
+DEFUN(no_ipv6_ospf6_cost, no_ipv6_ospf6_cost_cmd,
+ "no ipv6 ospf6 cost [(1-65535)]",
+ NO_STR IP6_STR OSPF6_STR "Calculate interface cost from bandwidth\n"
+ "Outgoing metric of this interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
@@ -2023,12 +2010,11 @@ DEFUN (no_ipv6_ospf6_cost,
return CMD_SUCCESS;
}
-DEFUN (auto_cost_reference_bandwidth,
- auto_cost_reference_bandwidth_cmd,
- "auto-cost reference-bandwidth (1-4294967)",
- "Calculate OSPF interface cost according to bandwidth\n"
- "Use reference bandwidth method to assign OSPF cost\n"
- "The reference bandwidth in terms of Mbits per second\n")
+DEFUN(auto_cost_reference_bandwidth, auto_cost_reference_bandwidth_cmd,
+ "auto-cost reference-bandwidth (1-4294967)",
+ "Calculate OSPF interface cost according to bandwidth\n"
+ "Use reference bandwidth method to assign OSPF cost\n"
+ "The reference bandwidth in terms of Mbits per second\n")
{
VTY_DECLVAR_CONTEXT(ospf6, o);
int idx_number = 2;
@@ -2055,13 +2041,11 @@ DEFUN (auto_cost_reference_bandwidth,
return CMD_SUCCESS;
}
-DEFUN (no_auto_cost_reference_bandwidth,
- no_auto_cost_reference_bandwidth_cmd,
- "no auto-cost reference-bandwidth [(1-4294967)]",
- NO_STR
- "Calculate OSPF interface cost according to bandwidth\n"
- "Use reference bandwidth method to assign OSPF cost\n"
- "The reference bandwidth in terms of Mbits per second\n")
+DEFUN(no_auto_cost_reference_bandwidth, no_auto_cost_reference_bandwidth_cmd,
+ "no auto-cost reference-bandwidth [(1-4294967)]",
+ NO_STR "Calculate OSPF interface cost according to bandwidth\n"
+ "Use reference bandwidth method to assign OSPF cost\n"
+ "The reference bandwidth in terms of Mbits per second\n")
{
VTY_DECLVAR_CONTEXT(ospf6, o);
struct ospf6_area *oa;
@@ -2080,11 +2064,10 @@ DEFUN (no_auto_cost_reference_bandwidth,
}
-DEFUN (ospf6_write_multiplier,
- ospf6_write_multiplier_cmd,
- "write-multiplier (1-100)",
- "Write multiplier\n"
- "Maximum number of interface serviced per write\n")
+DEFUN(ospf6_write_multiplier, ospf6_write_multiplier_cmd,
+ "write-multiplier (1-100)",
+ "Write multiplier\n"
+ "Maximum number of interface serviced per write\n")
{
VTY_DECLVAR_CONTEXT(ospf6, o);
uint32_t write_oi_count;
@@ -2099,12 +2082,10 @@ DEFUN (ospf6_write_multiplier,
return CMD_SUCCESS;
}
-DEFUN (no_ospf6_write_multiplier,
- no_ospf6_write_multiplier_cmd,
- "no write-multiplier (1-100)",
- NO_STR
- "Write multiplier\n"
- "Maximum number of interface serviced per write\n")
+DEFUN(no_ospf6_write_multiplier, no_ospf6_write_multiplier_cmd,
+ "no write-multiplier (1-100)",
+ NO_STR "Write multiplier\n"
+ "Maximum number of interface serviced per write\n")
{
VTY_DECLVAR_CONTEXT(ospf6, o);
@@ -2112,13 +2093,9 @@ DEFUN (no_ospf6_write_multiplier,
return CMD_SUCCESS;
}
-DEFUN (ipv6_ospf6_hellointerval,
- ipv6_ospf6_hellointerval_cmd,
- "ipv6 ospf6 hello-interval (1-65535)",
- IP6_STR
- OSPF6_STR
- "Time between HELLO packets\n"
- SECONDS_STR)
+DEFUN(ipv6_ospf6_hellointerval, ipv6_ospf6_hellointerval_cmd,
+ "ipv6 ospf6 hello-interval (1-65535)",
+ IP6_STR OSPF6_STR "Time between HELLO packets\n" SECONDS_STR)
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_number = 3;
@@ -2146,23 +2123,15 @@ DEFUN (ipv6_ospf6_hellointerval,
return CMD_SUCCESS;
}
-ALIAS (ipv6_ospf6_hellointerval,
- no_ipv6_ospf6_hellointerval_cmd,
- "no ipv6 ospf6 hello-interval [(1-65535)]",
- NO_STR
- IP6_STR
- OSPF6_STR
- "Time between HELLO packets\n"
- SECONDS_STR)
+ALIAS(ipv6_ospf6_hellointerval, no_ipv6_ospf6_hellointerval_cmd,
+ "no ipv6 ospf6 hello-interval [(1-65535)]",
+ NO_STR IP6_STR OSPF6_STR "Time between HELLO packets\n" SECONDS_STR)
/* interface variable set command */
-DEFUN (ipv6_ospf6_deadinterval,
- ipv6_ospf6_deadinterval_cmd,
- "ipv6 ospf6 dead-interval (1-65535)",
- IP6_STR
- OSPF6_STR
- "Interval time after which a neighbor is declared down\n"
- SECONDS_STR)
+DEFUN(ipv6_ospf6_deadinterval, ipv6_ospf6_deadinterval_cmd,
+ "ipv6 ospf6 dead-interval (1-65535)",
+ IP6_STR OSPF6_STR
+ "Interval time after which a neighbor is declared down\n" SECONDS_STR)
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_number = 3;
@@ -2180,22 +2149,16 @@ DEFUN (ipv6_ospf6_deadinterval,
return CMD_SUCCESS;
}
-ALIAS (ipv6_ospf6_deadinterval,
- no_ipv6_ospf6_deadinterval_cmd,
- "no ipv6 ospf6 dead-interval [(1-65535)]",
- NO_STR
- IP6_STR
- OSPF6_STR
- "Interval time after which a neighbor is declared down\n"
- SECONDS_STR)
+ALIAS(ipv6_ospf6_deadinterval, no_ipv6_ospf6_deadinterval_cmd,
+ "no ipv6 ospf6 dead-interval [(1-65535)]",
+ NO_STR IP6_STR OSPF6_STR
+ "Interval time after which a neighbor is declared down\n" SECONDS_STR)
DEFPY(ipv6_ospf6_gr_hdelay, ipv6_ospf6_gr_hdelay_cmd,
"ipv6 ospf6 graceful-restart hello-delay (1-1800)",
- IP6_STR
- OSPF6_STR
- "Graceful Restart parameters\n"
- "Delay the sending of the first hello packets.\n"
- "Delay in seconds\n")
+ IP6_STR OSPF6_STR "Graceful Restart parameters\n"
+ "Delay the sending of the first hello packets.\n"
+ "Delay in seconds\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
@@ -2212,12 +2175,9 @@ DEFPY(ipv6_ospf6_gr_hdelay, ipv6_ospf6_gr_hdelay_cmd,
DEFPY(no_ipv6_ospf6_gr_hdelay, no_ipv6_ospf6_gr_hdelay_cmd,
"no ipv6 ospf6 graceful-restart hello-delay [(1-1800)]",
- NO_STR
- IP6_STR
- OSPF6_STR
- "Graceful Restart parameters\n"
- "Delay the sending of the first hello packets.\n"
- "Delay in seconds\n")
+ NO_STR IP6_STR OSPF6_STR "Graceful Restart parameters\n"
+ "Delay the sending of the first hello packets.\n"
+ "Delay in seconds\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
@@ -2234,13 +2194,9 @@ DEFPY(no_ipv6_ospf6_gr_hdelay, no_ipv6_ospf6_gr_hdelay_cmd,
}
/* interface variable set command */
-DEFUN (ipv6_ospf6_transmitdelay,
- ipv6_ospf6_transmitdelay_cmd,
- "ipv6 ospf6 transmit-delay (1-3600)",
- IP6_STR
- OSPF6_STR
- "Link state transmit delay\n"
- SECONDS_STR)
+DEFUN(ipv6_ospf6_transmitdelay, ipv6_ospf6_transmitdelay_cmd,
+ "ipv6 ospf6 transmit-delay (1-3600)",
+ IP6_STR OSPF6_STR "Link state transmit delay\n" SECONDS_STR)
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_number = 3;
@@ -2258,23 +2214,15 @@ DEFUN (ipv6_ospf6_transmitdelay,
return CMD_SUCCESS;
}
-ALIAS (ipv6_ospf6_transmitdelay,
- no_ipv6_ospf6_transmitdelay_cmd,
- "no ipv6 ospf6 transmit-delay [(1-3600)]",
- NO_STR
- IP6_STR
- OSPF6_STR
- "Link state transmit delay\n"
- SECONDS_STR)
+ALIAS(ipv6_ospf6_transmitdelay, no_ipv6_ospf6_transmitdelay_cmd,
+ "no ipv6 ospf6 transmit-delay [(1-3600)]",
+ NO_STR IP6_STR OSPF6_STR "Link state transmit delay\n" SECONDS_STR)
/* interface variable set command */
-DEFUN (ipv6_ospf6_retransmitinterval,
- ipv6_ospf6_retransmitinterval_cmd,
- "ipv6 ospf6 retransmit-interval (1-65535)",
- IP6_STR
- OSPF6_STR
- "Time between retransmitting lost link state advertisements\n"
- SECONDS_STR)
+DEFUN(ipv6_ospf6_retransmitinterval, ipv6_ospf6_retransmitinterval_cmd,
+ "ipv6 ospf6 retransmit-interval (1-65535)",
+ IP6_STR OSPF6_STR
+ "Time between retransmitting lost link state advertisements\n" SECONDS_STR)
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_number = 3;
@@ -2292,23 +2240,16 @@ DEFUN (ipv6_ospf6_retransmitinterval,
return CMD_SUCCESS;
}
-ALIAS (ipv6_ospf6_retransmitinterval,
- no_ipv6_ospf6_retransmitinterval_cmd,
- "no ipv6 ospf6 retransmit-interval [(1-65535)]",
- NO_STR
- IP6_STR
- OSPF6_STR
- "Time between retransmitting lost link state advertisements\n"
- SECONDS_STR)
+ALIAS(ipv6_ospf6_retransmitinterval, no_ipv6_ospf6_retransmitinterval_cmd,
+ "no ipv6 ospf6 retransmit-interval [(1-65535)]",
+ NO_STR IP6_STR OSPF6_STR
+ "Time between retransmitting lost link state advertisements\n" SECONDS_STR)
/* interface variable set command */
-DEFUN (ipv6_ospf6_priority,
- ipv6_ospf6_priority_cmd,
- "ipv6 ospf6 priority (0-255)",
- IP6_STR
- OSPF6_STR
- "Router priority\n"
- "Priority value\n")
+DEFUN(ipv6_ospf6_priority, ipv6_ospf6_priority_cmd,
+ "ipv6 ospf6 priority (0-255)",
+ IP6_STR OSPF6_STR "Router priority\n"
+ "Priority value\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_number = 3;
@@ -2324,10 +2265,9 @@ DEFUN (ipv6_ospf6_priority,
? OSPF6_INTERFACE_PRIORITY
: strtoul(argv[idx_number]->arg, NULL, 10);
- if (oi->area
- && (oi->state == OSPF6_INTERFACE_DROTHER
- || oi->state == OSPF6_INTERFACE_BDR
- || oi->state == OSPF6_INTERFACE_DR)) {
+ if (oi->area && (oi->state == OSPF6_INTERFACE_DROTHER ||
+ oi->state == OSPF6_INTERFACE_BDR ||
+ oi->state == OSPF6_INTERFACE_DR)) {
if (ospf6_interface_state_change(dr_election(oi), oi) == -1)
OSPF6_LINK_LSA_SCHEDULE(oi);
}
@@ -2335,22 +2275,15 @@ DEFUN (ipv6_ospf6_priority,
return CMD_SUCCESS;
}
-ALIAS (ipv6_ospf6_priority,
- no_ipv6_ospf6_priority_cmd,
- "no ipv6 ospf6 priority [(0-255)]",
- NO_STR
- IP6_STR
- OSPF6_STR
- "Router priority\n"
- "Priority value\n")
+ALIAS(ipv6_ospf6_priority, no_ipv6_ospf6_priority_cmd,
+ "no ipv6 ospf6 priority [(0-255)]",
+ NO_STR IP6_STR OSPF6_STR "Router priority\n"
+ "Priority value\n")
-DEFUN (ipv6_ospf6_instance,
- ipv6_ospf6_instance_cmd,
- "ipv6 ospf6 instance-id (0-255)",
- IP6_STR
- OSPF6_STR
- "Instance ID for this interface\n"
- "Instance ID value\n")
+DEFUN(ipv6_ospf6_instance, ipv6_ospf6_instance_cmd,
+ "ipv6 ospf6 instance-id (0-255)",
+ IP6_STR OSPF6_STR "Instance ID for this interface\n"
+ "Instance ID value\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_number = 3;
@@ -2368,22 +2301,14 @@ DEFUN (ipv6_ospf6_instance,
return CMD_SUCCESS;
}
-ALIAS (ipv6_ospf6_instance,
- no_ipv6_ospf6_instance_cmd,
- "no ipv6 ospf6 instance-id [(0-255)]",
- NO_STR
- IP6_STR
- OSPF6_STR
- "Instance ID for this interface\n"
- "Instance ID value\n")
+ALIAS(ipv6_ospf6_instance, no_ipv6_ospf6_instance_cmd,
+ "no ipv6 ospf6 instance-id [(0-255)]",
+ NO_STR IP6_STR OSPF6_STR "Instance ID for this interface\n"
+ "Instance ID value\n")
-DEFUN (ipv6_ospf6_passive,
- ipv6_ospf6_passive_cmd,
- "ipv6 ospf6 passive",
- IP6_STR
- OSPF6_STR
- "Passive interface; no adjacency will be formed on this interface\n"
- )
+DEFUN(ipv6_ospf6_passive, ipv6_ospf6_passive_cmd, "ipv6 ospf6 passive",
+ IP6_STR OSPF6_STR
+ "Passive interface; no adjacency will be formed on this interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
@@ -2409,14 +2334,9 @@ DEFUN (ipv6_ospf6_passive,
return CMD_SUCCESS;
}
-DEFUN (no_ipv6_ospf6_passive,
- no_ipv6_ospf6_passive_cmd,
- "no ipv6 ospf6 passive",
- NO_STR
- IP6_STR
- OSPF6_STR
- "passive interface: No Adjacency will be formed on this I/F\n"
- )
+DEFUN(no_ipv6_ospf6_passive, no_ipv6_ospf6_passive_cmd, "no ipv6 ospf6 passive",
+ NO_STR IP6_STR OSPF6_STR
+ "passive interface: No Adjacency will be formed on this I/F\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
@@ -2439,13 +2359,8 @@ DEFUN (no_ipv6_ospf6_passive,
return CMD_SUCCESS;
}
-DEFUN (ipv6_ospf6_mtu_ignore,
- ipv6_ospf6_mtu_ignore_cmd,
- "ipv6 ospf6 mtu-ignore",
- IP6_STR
- OSPF6_STR
- "Disable MTU mismatch detection on this interface\n"
- )
+DEFUN(ipv6_ospf6_mtu_ignore, ipv6_ospf6_mtu_ignore_cmd, "ipv6 ospf6 mtu-ignore",
+ IP6_STR OSPF6_STR "Disable MTU mismatch detection on this interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
@@ -2461,14 +2376,10 @@ DEFUN (ipv6_ospf6_mtu_ignore,
return CMD_SUCCESS;
}
-DEFUN (no_ipv6_ospf6_mtu_ignore,
- no_ipv6_ospf6_mtu_ignore_cmd,
- "no ipv6 ospf6 mtu-ignore",
- NO_STR
- IP6_STR
- OSPF6_STR
- "Disable MTU mismatch detection on this interface\n"
- )
+DEFUN(no_ipv6_ospf6_mtu_ignore, no_ipv6_ospf6_mtu_ignore_cmd,
+ "no ipv6 ospf6 mtu-ignore",
+ NO_STR IP6_STR OSPF6_STR
+ "Disable MTU mismatch detection on this interface\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
@@ -2484,15 +2395,11 @@ DEFUN (no_ipv6_ospf6_mtu_ignore,
return CMD_SUCCESS;
}
-DEFUN (ipv6_ospf6_advertise_prefix_list,
- ipv6_ospf6_advertise_prefix_list_cmd,
- "ipv6 ospf6 advertise prefix-list WORD",
- IP6_STR
- OSPF6_STR
- "Advertising options\n"
- "Filter prefix using prefix-list\n"
- "Prefix list name\n"
- )
+DEFUN(ipv6_ospf6_advertise_prefix_list, ipv6_ospf6_advertise_prefix_list_cmd,
+ "ipv6 ospf6 advertise prefix-list PREFIXLIST6_NAME",
+ IP6_STR OSPF6_STR "Advertising options\n"
+ "Filter prefix using prefix-list\n"
+ "Prefix list name\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_word = 4;
@@ -2522,15 +2429,12 @@ DEFUN (ipv6_ospf6_advertise_prefix_list,
return CMD_SUCCESS;
}
-DEFUN (no_ipv6_ospf6_advertise_prefix_list,
- no_ipv6_ospf6_advertise_prefix_list_cmd,
- "no ipv6 ospf6 advertise prefix-list [WORD]",
- NO_STR
- IP6_STR
- OSPF6_STR
- "Advertising options\n"
- "Filter prefix using prefix-list\n"
- "Prefix list name\n")
+DEFUN(no_ipv6_ospf6_advertise_prefix_list,
+ no_ipv6_ospf6_advertise_prefix_list_cmd,
+ "no ipv6 ospf6 advertise prefix-list [PREFIXLIST6_NAME]",
+ NO_STR IP6_STR OSPF6_STR "Advertising options\n"
+ "Filter prefix using prefix-list\n"
+ "Prefix list name\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
@@ -2558,15 +2462,12 @@ DEFUN (no_ipv6_ospf6_advertise_prefix_list,
return CMD_SUCCESS;
}
-DEFUN (ipv6_ospf6_network,
- ipv6_ospf6_network_cmd,
- "ipv6 ospf6 network <broadcast|point-to-point>",
- IP6_STR
- OSPF6_STR
- "Network type\n"
- "Specify OSPF6 broadcast network\n"
- "Specify OSPF6 point-to-point network\n"
- )
+DEFUN(ipv6_ospf6_network, ipv6_ospf6_network_cmd,
+ "ipv6 ospf6 network <broadcast|point-to-point|point-to-multipoint>",
+ IP6_STR OSPF6_STR "Network type\n"
+ "Specify OSPF6 broadcast network\n"
+ "Specify OSPF6 point-to-point network\n"
+ "Specify OSPF6 point-to-multipoint network\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_network = 3;
@@ -2591,6 +2492,11 @@ DEFUN (ipv6_ospf6_network,
return CMD_SUCCESS;
}
oi->type = OSPF_IFTYPE_POINTOPOINT;
+ } else if (strncmp(argv[idx_network]->arg, "point-to-m", 10) == 0) {
+ if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) {
+ return CMD_SUCCESS;
+ }
+ oi->type = OSPF_IFTYPE_POINTOMULTIPOINT;
}
/* Reset the interface */
@@ -2600,15 +2506,11 @@ DEFUN (ipv6_ospf6_network,
return CMD_SUCCESS;
}
-DEFUN (no_ipv6_ospf6_network,
- no_ipv6_ospf6_network_cmd,
- "no ipv6 ospf6 network [<broadcast|point-to-point>]",
- NO_STR
- IP6_STR
- OSPF6_STR
- "Set default network type\n"
- "Specify OSPF6 broadcast network\n"
- "Specify OSPF6 point-to-point network\n")
+DEFUN(no_ipv6_ospf6_network, no_ipv6_ospf6_network_cmd,
+ "no ipv6 ospf6 network [<broadcast|point-to-point>]",
+ NO_STR IP6_STR OSPF6_STR "Set default network type\n"
+ "Specify OSPF6 broadcast network\n"
+ "Specify OSPF6 point-to-point network\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
@@ -2617,9 +2519,8 @@ DEFUN (no_ipv6_ospf6_network,
assert(ifp);
oi = (struct ospf6_interface *)ifp->info;
- if (oi == NULL) {
+ if (oi == NULL)
return CMD_SUCCESS;
- }
oi->type_cfg = false;
@@ -2636,6 +2537,95 @@ DEFUN (no_ipv6_ospf6_network,
return CMD_SUCCESS;
}
+DEFPY(ipv6_ospf6_p2xp_only_cfg_neigh, ipv6_ospf6_p2xp_only_cfg_neigh_cmd,
+ "[no] ipv6 ospf6 p2p-p2mp config-neighbors-only",
+ NO_STR IP6_STR OSPF6_STR
+ "Point-to-point and Point-to-Multipoint parameters\n"
+ "Only form adjacencies with explicitly configured neighbors\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct ospf6_interface *oi = ifp->info;
+
+ if (no) {
+ if (!oi)
+ return CMD_SUCCESS;
+
+ oi->p2xp_only_cfg_neigh = false;
+ return CMD_SUCCESS;
+ }
+
+ if (!oi)
+ oi = ospf6_interface_create(ifp);
+
+ oi->p2xp_only_cfg_neigh = true;
+ return CMD_SUCCESS;
+}
+
+DEFPY(ipv6_ospf6_p2xp_no_multicast_hello, ipv6_ospf6_p2xp_no_multicast_hello_cmd,
+ "[no] ipv6 ospf6 p2p-p2mp disable-multicast-hello",
+ NO_STR IP6_STR OSPF6_STR
+ "Point-to-point and Point-to-Multipoint parameters\n"
+ "Do not send multicast hellos\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct ospf6_interface *oi = ifp->info;
+
+ if (no) {
+ if (!oi)
+ return CMD_SUCCESS;
+
+ oi->p2xp_no_multicast_hello = false;
+ return CMD_SUCCESS;
+ }
+
+ if (!oi)
+ oi = ospf6_interface_create(ifp);
+
+ oi->p2xp_no_multicast_hello = true;
+ return CMD_SUCCESS;
+}
+
+DEFPY(ipv6_ospf6_p2xp_connected_pfx, ipv6_ospf6_p2xp_connected_pfx_cmd,
+ "[no] ipv6 ospf6 p2p-p2mp connected-prefixes <include$incl|exclude$excl>",
+ NO_STR IP6_STR OSPF6_STR
+ "Point-to-point and Point-to-Multipoint parameters\n"
+ "Adjust handling of directly connected prefixes\n"
+ "Advertise prefixes and own /128 (default for PtP)\n"
+ "Ignore, only advertise own /128 (default for PtMP)\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct ospf6_interface *oi = ifp->info;
+ bool old_incl, old_excl;
+
+ if (no && !oi)
+ return CMD_SUCCESS;
+
+ if (!oi)
+ oi = ospf6_interface_create(ifp);
+
+ old_incl = oi->p2xp_connected_pfx_include;
+ old_excl = oi->p2xp_connected_pfx_exclude;
+ oi->p2xp_connected_pfx_include = false;
+ oi->p2xp_connected_pfx_exclude = false;
+
+ if (incl && !no)
+ oi->p2xp_connected_pfx_include = true;
+ if (excl && !no)
+ oi->p2xp_connected_pfx_exclude = true;
+
+ if (oi->p2xp_connected_pfx_include != old_incl ||
+ oi->p2xp_connected_pfx_exclude != old_excl)
+ ospf6_interface_connected_route_update(ifp);
+ return CMD_SUCCESS;
+}
+
+ALIAS(ipv6_ospf6_p2xp_connected_pfx, no_ipv6_ospf6_p2xp_connected_pfx_cmd,
+ "no ipv6 ospf6 p2p-p2mp connected-prefixes",
+ NO_STR IP6_STR OSPF6_STR
+ "Point-to-point and Point-to-Multipoint parameters\n"
+ "Adjust handling of directly connected prefixes\n")
+
+
static int config_write_ospf6_interface(struct vty *vty, struct vrf *vrf)
{
struct ospf6_interface *oi;
@@ -2695,7 +2685,10 @@ static int config_write_ospf6_interface(struct vty *vty, struct vrf *vrf)
if (oi->mtu_ignore)
vty_out(vty, " ipv6 ospf6 mtu-ignore\n");
- if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOPOINT)
+ if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
+ vty_out(vty,
+ " ipv6 ospf6 network point-to-multipoint\n");
+ else if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOPOINT)
vty_out(vty, " ipv6 ospf6 network point-to-point\n");
else if (oi->type_cfg && oi->type == OSPF_IFTYPE_BROADCAST)
vty_out(vty, " ipv6 ospf6 network broadcast\n");
@@ -2704,7 +2697,22 @@ static int config_write_ospf6_interface(struct vty *vty, struct vrf *vrf)
vty_out(vty,
" ipv6 ospf6 graceful-restart hello-delay %u\n",
oi->gr.hello_delay.interval);
+ if (oi->p2xp_only_cfg_neigh)
+ vty_out(vty,
+ " ipv6 ospf6 p2p-p2mp config-neighbors-only\n");
+ if (oi->p2xp_no_multicast_hello)
+ vty_out(vty,
+ " ipv6 ospf6 p2p-p2mp disable-multicast-hello\n");
+
+ if (oi->p2xp_connected_pfx_include)
+ vty_out(vty,
+ " ipv6 ospf6 p2p-p2mp connected-prefixes include\n");
+ else if (oi->p2xp_connected_pfx_exclude)
+ vty_out(vty,
+ " ipv6 ospf6 p2p-p2mp connected-prefixes exclude\n");
+
+ config_write_ospf6_p2xp_neighbor(vty, oi);
ospf6_bfd_write_config(vty, oi);
ospf6_auth_write_config(vty, &oi->at_data);
@@ -2742,10 +2750,10 @@ static int ospf6_ifp_create(struct interface *ifp)
static int ospf6_ifp_up(struct interface *ifp)
{
if (IS_OSPF6_DEBUG_ZEBRA(RECV))
- zlog_debug(
- "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
- ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
- ifp->metric, ifp->mtu6, ifp->bandwidth);
+ zlog_debug("Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
+ ifp->name, ifp->ifindex,
+ (unsigned long long)ifp->flags, ifp->metric,
+ ifp->mtu6, ifp->bandwidth);
ospf6_interface_state_update(ifp);
@@ -2755,10 +2763,10 @@ static int ospf6_ifp_up(struct interface *ifp)
static int ospf6_ifp_down(struct interface *ifp)
{
if (IS_OSPF6_DEBUG_ZEBRA(RECV))
- zlog_debug(
- "Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
- ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
- ifp->metric, ifp->mtu6, ifp->bandwidth);
+ zlog_debug("Zebra Interface state change: %s index %d flags %llx metric %d mtu %d bandwidth %d",
+ ifp->name, ifp->ifindex,
+ (unsigned long long)ifp->flags, ifp->metric,
+ ifp->mtu6, ifp->bandwidth);
ospf6_interface_state_update(ifp);
@@ -2785,13 +2793,14 @@ void ospf6_interface_init(void)
{
/* Install interface node. */
if_cmd_init(config_write_interface);
- if_zapi_callbacks(ospf6_ifp_create, ospf6_ifp_up,
- ospf6_ifp_down, ospf6_ifp_destroy);
+ hook_register_prio(if_real, 0, ospf6_ifp_create);
+ hook_register_prio(if_up, 0, ospf6_ifp_up);
+ hook_register_prio(if_down, 0, ospf6_ifp_down);
+ hook_register_prio(if_unreal, 0, ospf6_ifp_destroy);
install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
- install_element(VIEW_NODE,
- &show_ipv6_ospf6_interface_ifname_prefix_cmd);
+ install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd);
install_element(VIEW_NODE, &show_ipv6_ospf6_interface_traffic_cmd);
install_element(INTERFACE_NODE, &ipv6_ospf6_area_cmd);
@@ -2829,6 +2838,11 @@ void ospf6_interface_init(void)
install_element(INTERFACE_NODE, &ipv6_ospf6_network_cmd);
install_element(INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
+ install_element(INTERFACE_NODE, &ipv6_ospf6_p2xp_only_cfg_neigh_cmd);
+ install_element(INTERFACE_NODE, &ipv6_ospf6_p2xp_no_multicast_hello_cmd);
+ install_element(INTERFACE_NODE, &ipv6_ospf6_p2xp_connected_pfx_cmd);
+ install_element(INTERFACE_NODE, &no_ipv6_ospf6_p2xp_connected_pfx_cmd);
+
/* reference bandwidth commands */
install_element(OSPF6_NODE, &auto_cost_reference_bandwidth_cmd);
install_element(OSPF6_NODE, &no_auto_cost_reference_bandwidth_cmd);
@@ -2859,16 +2873,9 @@ void ospf6_interface_clear(struct interface *ifp)
}
/* Clear interface */
-DEFUN (clear_ipv6_ospf6_interface,
- clear_ipv6_ospf6_interface_cmd,
- "clear ipv6 ospf6 [vrf NAME] interface [IFNAME]",
- CLEAR_STR
- IP6_STR
- OSPF6_STR
- VRF_CMD_HELP_STR
- INTERFACE_STR
- IFNAME_STR
- )
+DEFUN(clear_ipv6_ospf6_interface, clear_ipv6_ospf6_interface_cmd,
+ "clear ipv6 ospf6 [vrf NAME] interface [IFNAME]",
+ CLEAR_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR INTERFACE_STR IFNAME_STR)
{
struct vrf *vrf;
int idx_vrf = 3;
@@ -2909,26 +2916,16 @@ void install_element_ospf6_clear_interface(void)
install_element(ENABLE_NODE, &clear_ipv6_ospf6_interface_cmd);
}
-DEFUN (debug_ospf6_interface,
- debug_ospf6_interface_cmd,
- "debug ospf6 interface",
- DEBUG_STR
- OSPF6_STR
- "Debug OSPFv3 Interface\n"
- )
+DEFUN(debug_ospf6_interface, debug_ospf6_interface_cmd, "debug ospf6 interface",
+ DEBUG_STR OSPF6_STR "Debug OSPFv3 Interface\n")
{
OSPF6_DEBUG_INTERFACE_ON();
return CMD_SUCCESS;
}
-DEFUN (no_debug_ospf6_interface,
- no_debug_ospf6_interface_cmd,
- "no debug ospf6 interface",
- NO_STR
- DEBUG_STR
- OSPF6_STR
- "Debug OSPFv3 Interface\n"
- )
+DEFUN(no_debug_ospf6_interface, no_debug_ospf6_interface_cmd,
+ "no debug ospf6 interface",
+ NO_STR DEBUG_STR OSPF6_STR "Debug OSPFv3 Interface\n")
{
OSPF6_DEBUG_INTERFACE_OFF();
return CMD_SUCCESS;
@@ -2965,10 +2962,9 @@ void ospf6_auth_write_config(struct vty *vty, struct ospf6_auth_data *at_data)
DEFUN(ipv6_ospf6_intf_auth_trailer_keychain,
ipv6_ospf6_intf_auth_trailer_keychain_cmd,
"ipv6 ospf6 authentication keychain KEYCHAIN_NAME",
- IP6_STR OSPF6_STR
- "Enable authentication on this interface\n"
- "Keychain\n"
- "Keychain name\n")
+ IP6_STR OSPF6_STR "Enable authentication on this interface\n"
+ "Keychain\n"
+ "Keychain name\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int keychain_idx = 4;
@@ -2989,8 +2985,8 @@ DEFUN(ipv6_ospf6_intf_auth_trailer_keychain,
if (oi->at_data.keychain)
XFREE(MTYPE_OSPF6_AUTH_KEYCHAIN, oi->at_data.keychain);
- oi->at_data.keychain =
- XSTRDUP(MTYPE_OSPF6_AUTH_KEYCHAIN, argv[keychain_idx]->arg);
+ oi->at_data.keychain = XSTRDUP(MTYPE_OSPF6_AUTH_KEYCHAIN,
+ argv[keychain_idx]->arg);
return CMD_SUCCESS;
}
@@ -2998,10 +2994,9 @@ DEFUN(ipv6_ospf6_intf_auth_trailer_keychain,
DEFUN(no_ipv6_ospf6_intf_auth_trailer_keychain,
no_ipv6_ospf6_intf_auth_trailer_keychain_cmd,
"no ipv6 ospf6 authentication keychain [KEYCHAIN_NAME]",
- NO_STR IP6_STR OSPF6_STR
- "Enable authentication on this interface\n"
- "Keychain\n"
- "Keychain name\n")
+ NO_STR IP6_STR OSPF6_STR "Enable authentication on this interface\n"
+ "Keychain\n"
+ "Keychain name\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
@@ -3027,18 +3022,17 @@ DEFUN(ipv6_ospf6_intf_auth_trailer_key, ipv6_ospf6_intf_auth_trailer_key_cmd,
"ipv6 ospf6 authentication key-id (1-65535) hash-algo "
"<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512> "
"key WORD",
- IP6_STR OSPF6_STR
- "Authentication\n"
- "Key ID\n"
- "Key ID value\n"
- "Cryptographic-algorithm\n"
- "Use MD5 algorithm\n"
- "Use HMAC-SHA-1 algorithm\n"
- "Use HMAC-SHA-256 algorithm\n"
- "Use HMAC-SHA-384 algorithm\n"
- "Use HMAC-SHA-512 algorithm\n"
- "Password\n"
- "Password string (key)\n")
+ IP6_STR OSPF6_STR "Authentication\n"
+ "Key ID\n"
+ "Key ID value\n"
+ "Cryptographic-algorithm\n"
+ "Use MD5 algorithm\n"
+ "Use HMAC-SHA-1 algorithm\n"
+ "Use HMAC-SHA-256 algorithm\n"
+ "Use HMAC-SHA-384 algorithm\n"
+ "Use HMAC-SHA-512 algorithm\n"
+ "Password\n"
+ "Password string (key)\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int key_id_idx = 4;
@@ -3072,8 +3066,8 @@ DEFUN(ipv6_ospf6_intf_auth_trailer_key, ipv6_ospf6_intf_auth_trailer_key_cmd,
oi->at_data.key_id = (uint16_t)strtol(argv[key_id_idx]->arg, NULL, 10);
if (oi->at_data.auth_key)
XFREE(MTYPE_OSPF6_AUTH_MANUAL_KEY, oi->at_data.auth_key);
- oi->at_data.auth_key =
- XSTRDUP(MTYPE_OSPF6_AUTH_MANUAL_KEY, argv[password_idx]->arg);
+ oi->at_data.auth_key = XSTRDUP(MTYPE_OSPF6_AUTH_MANUAL_KEY,
+ argv[password_idx]->arg);
return CMD_SUCCESS;
}
@@ -3083,18 +3077,17 @@ DEFUN(no_ipv6_ospf6_intf_auth_trailer_key,
"no ipv6 ospf6 authentication key-id [(1-65535) hash-algo "
"<md5|hmac-sha-1|hmac-sha-256|hmac-sha-384|hmac-sha-512> "
"key WORD]",
- NO_STR IP6_STR OSPF6_STR
- "Authentication\n"
- "Key ID\n"
- "Key ID value\n"
- "Cryptographic-algorithm\n"
- "Use MD5 algorithm\n"
- "Use HMAC-SHA-1 algorithm\n"
- "Use HMAC-SHA-256 algorithm\n"
- "Use HMAC-SHA-384 algorithm\n"
- "Use HMAC-SHA-512 algorithm\n"
- "Password\n"
- "Password string (key)\n")
+ NO_STR IP6_STR OSPF6_STR "Authentication\n"
+ "Key ID\n"
+ "Key ID value\n"
+ "Cryptographic-algorithm\n"
+ "Use MD5 algorithm\n"
+ "Use HMAC-SHA-1 algorithm\n"
+ "Use HMAC-SHA-256 algorithm\n"
+ "Use HMAC-SHA-384 algorithm\n"
+ "Use HMAC-SHA-512 algorithm\n"
+ "Password\n"
+ "Password string (key)\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct ospf6_interface *oi;
diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h
index 5942df0..46a7c90 100644
--- a/ospf6d/ospf6_interface.h
+++ b/ospf6d/ospf6_interface.h
@@ -34,6 +34,25 @@ struct ospf6_auth_data {
uint32_t rx_drop; /* Pkt drop due to auth fail while reading */
};
+PREDECL_RBTREE_UNIQ(ospf6_if_p2xp_neighcfgs);
+
+struct ospf6_if_p2xp_neighcfg {
+ struct ospf6_if_p2xp_neighcfgs_item item;
+
+ struct ospf6_interface *ospf6_if;
+ struct in6_addr addr;
+
+ bool cfg_cost : 1;
+
+ uint32_t cost;
+ uint16_t poll_interval;
+
+ /* NULL if down */
+ struct ospf6_neighbor *active;
+
+ struct event *t_unicast_hello;
+};
+
/* Interface structure */
struct ospf6_interface {
/* IF info from zebra */
@@ -66,6 +85,20 @@ struct ospf6_interface {
uint8_t type;
bool type_cfg;
+ /* P2P/P2MP behavior: */
+
+ /* disable hellos on standard multicast? */
+ bool p2xp_no_multicast_hello;
+ /* only allow explicitly configured neighbors? */
+ bool p2xp_only_cfg_neigh;
+ /* override mode default for advertising connected prefixes.
+ * both false by default (= do include for PtP, exclude for PtMP)
+ */
+ bool p2xp_connected_pfx_include;
+ bool p2xp_connected_pfx_exclude;
+
+ struct ospf6_if_p2xp_neighcfgs_head p2xp_neighs;
+
/* Router Priority */
uint8_t priority;
@@ -171,15 +204,16 @@ struct ospf6_interface {
DECLARE_QOBJ_TYPE(ospf6_interface);
/* interface state */
-#define OSPF6_INTERFACE_NONE 0
-#define OSPF6_INTERFACE_DOWN 1
-#define OSPF6_INTERFACE_LOOPBACK 2
-#define OSPF6_INTERFACE_WAITING 3
-#define OSPF6_INTERFACE_POINTTOPOINT 4
-#define OSPF6_INTERFACE_DROTHER 5
-#define OSPF6_INTERFACE_BDR 6
-#define OSPF6_INTERFACE_DR 7
-#define OSPF6_INTERFACE_MAX 8
+#define OSPF6_INTERFACE_NONE 0
+#define OSPF6_INTERFACE_DOWN 1
+#define OSPF6_INTERFACE_LOOPBACK 2
+#define OSPF6_INTERFACE_WAITING 3
+#define OSPF6_INTERFACE_POINTTOPOINT 4
+#define OSPF6_INTERFACE_POINTTOMULTIPOINT 5
+#define OSPF6_INTERFACE_DROTHER 6
+#define OSPF6_INTERFACE_BDR 7
+#define OSPF6_INTERFACE_DR 8
+#define OSPF6_INTERFACE_MAX 9
extern const char *const ospf6_interface_state_str[];
@@ -197,7 +231,7 @@ extern const char *const ospf6_interface_state_str[];
#define OSPF6_INTERFACE_TRANSDELAY 1
#define OSPF6_INTERFACE_INSTANCE_ID 0
#define OSPF6_INTERFACE_BANDWIDTH 10000 /* Mbps */
-#define OSPF6_REFERENCE_BANDWIDTH 100000 /* Mbps */
+#define OSPF6_REFERENCE_BANDWIDTH 100000 /* Kbps */
#define OSPF6_INTERFACE_SSO_RETRY_INT 1
#define OSPF6_INTERFACE_SSO_RETRY_MAX 5
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index eb5514a..cb03675 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -321,13 +321,14 @@ void ospf6_router_lsa_originate(struct event *thread)
}
/* Point-to-Point interfaces */
- if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
+ if (oi->type == OSPF_IFTYPE_POINTOPOINT
+ || oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) {
for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, j, on)) {
if (on->state != OSPF6_NEIGHBOR_FULL)
continue;
lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
- lsdesc->metric = htons(oi->cost);
+ lsdesc->metric = htons(ospf6_neighbor_cost(on));
lsdesc->interface_id =
htonl(oi->interface->ifindex);
lsdesc->neighbor_interface_id =
@@ -1068,6 +1069,7 @@ void ospf6_intra_prefix_lsa_originate_stub(struct event *thread)
if (oi->state != OSPF6_INTERFACE_LOOPBACK
&& oi->state != OSPF6_INTERFACE_POINTTOPOINT
+ && oi->state != OSPF6_INTERFACE_POINTTOMULTIPOINT
&& full_count != 0) {
if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
zlog_debug(" Interface %s is not stub, ignore",
diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c
index 9323045..17966e7 100644
--- a/ospf6d/ospf6_main.c
+++ b/ospf6d/ospf6_main.c
@@ -38,8 +38,13 @@
/* Default configuration file name for ospf6d. */
#define OSPF6_DEFAULT_CONFIG "ospf6d.conf"
-/* Default port values. */
-#define OSPF6_VTY_PORT 2606
+/* GR and auth trailer persistent state */
+#define OSPF6D_STATE_NAME "%s/ospf6d.json", frr_libstatedir
+#define OSPF6D_COMPAT_STATE_NAME "%s/ospf6d-gr.json", frr_runstatedir
+/* for extra confusion, "ospf6d-at-seq-no.dat" is handled directly in
+ * ospf6_auth_trailer.c; the alternative would be somehow merging JSON which
+ * is excessive for just supporting a legacy compatibility file location
+ */
/* ospf6d privileges */
zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND, ZCAP_SYS_ADMIN};
@@ -103,7 +108,11 @@ static void __attribute__((noreturn)) ospf6_exit(int status)
zclient_free(zclient);
}
+ ospf6_master_delete();
+
frr_fini();
+
+ keychain_terminate();
exit(status);
}
@@ -162,16 +171,31 @@ static const struct frr_yang_module_info *const ospf6d_yang_modules[] = {
&frr_ospf6_route_map_info,
};
-FRR_DAEMON_INFO(ospf6d, OSPF6, .vty_port = OSPF6_VTY_PORT,
+/* actual paths filled in main() */
+static char state_path[512];
+static char state_compat_path[512];
+static char *state_paths[] = {
+ state_path,
+ state_compat_path,
+ NULL,
+};
- .proghelp = "Implementation of the OSPFv3 routing protocol.",
+/* clang-format off */
+FRR_DAEMON_INFO(ospf6d, OSPF6,
+ .vty_port = OSPF6_VTY_PORT,
+ .proghelp = "Implementation of the OSPFv3 routing protocol.",
- .signals = ospf6_signals,
- .n_signals = array_size(ospf6_signals),
+ .signals = ospf6_signals,
+ .n_signals = array_size(ospf6_signals),
- .privs = &ospf6d_privs, .yang_modules = ospf6d_yang_modules,
- .n_yang_modules = array_size(ospf6d_yang_modules),
+ .privs = &ospf6d_privs,
+
+ .yang_modules = ospf6d_yang_modules,
+ .n_yang_modules = array_size(ospf6d_yang_modules),
+
+ .state_paths = state_paths,
);
+/* clang-format on */
/* Max wait time for config to load before accepting hellos */
#define OSPF6_PRE_CONFIG_MAX_WAIT_SECONDS 600
@@ -229,6 +253,10 @@ int main(int argc, char *argv[], char *envp[])
exit(1);
}
+ snprintf(state_path, sizeof(state_path), OSPF6D_STATE_NAME);
+ snprintf(state_compat_path, sizeof(state_compat_path),
+ OSPF6D_COMPAT_STATE_NAME);
+
/* OSPF6 master init. */
ospf6_master_init(frr_init());
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c
index 07da9a5..d13799c 100644
--- a/ospf6d/ospf6_message.c
+++ b/ospf6d/ospf6_message.c
@@ -268,6 +268,18 @@ static struct ospf6_packet *ospf6_packet_new(size_t size)
return new;
}
+static struct ospf6_packet *ospf6_packet_dup(struct ospf6_packet *old)
+{
+ struct ospf6_packet *new;
+
+ new = XCALLOC(MTYPE_OSPF6_PACKET, sizeof(struct ospf6_packet));
+ new->s = stream_dup(old->s);
+ new->dst = old->dst;
+ new->length = old->length;
+
+ return new;
+}
+
static void ospf6_packet_free(struct ospf6_packet *op)
{
if (op->s)
@@ -407,6 +419,25 @@ static void ospf6_hello_recv(struct in6_addr *src, struct in6_addr *dst,
hello = (struct ospf6_hello *)((caddr_t)oh
+ sizeof(struct ospf6_header));
+ if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT
+ || oi->state == OSPF6_INTERFACE_POINTTOMULTIPOINT)
+ && oi->p2xp_only_cfg_neigh) {
+ /* NEVER, never, ever, do this on broadcast (or NBMA)!
+ * DR/BDR election requires everyone to talk to everyone else
+ * only for PtP/PtMP we can be selective in adjacencies!
+ */
+ struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
+
+ p2xp_cfg = ospf6_if_p2xp_find(oi, src);
+ if (!p2xp_cfg) {
+ if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV_HDR))
+ zlog_debug(
+ "ignoring PtP/PtMP hello from %pI6, neighbor not configured",
+ src);
+ return;
+ }
+ }
+
/* HelloInterval check */
if (ntohs(hello->hello_interval) != oi->hello_interval) {
zlog_warn(
@@ -479,7 +510,7 @@ static void ospf6_hello_recv(struct in6_addr *src, struct in6_addr *dst,
on->hello_in++;
/* Always override neighbor's source address */
- memcpy(&on->linklocal_addr, src, sizeof(struct in6_addr));
+ ospf6_neighbor_lladdr_set(on, src);
/* Neighbor ifindex check */
if (on->ifindex != (ifindex_t)ntohl(hello->interface_id)) {
@@ -631,8 +662,8 @@ static void ospf6_dbdesc_recv_master(struct ospf6_header *oh,
"Neighbor state is not ExStart, ignore");
return;
}
- /* else fall through to ExStart */
- /* fallthru */
+ /* else fall through to ExStart */
+ fallthrough;
case OSPF6_NEIGHBOR_EXSTART:
/* if neighbor obeys us as our slave, schedule negotiation_done
and process LSA Headers. Otherwise, ignore this message */
@@ -650,8 +681,8 @@ static void ospf6_dbdesc_recv_master(struct ospf6_header *oh,
on->ospf6_if->interface->vrf->name, on->name);
return;
}
- /* fall through to exchange */
-
+ /* fall through to exchange */
+ fallthrough;
case OSPF6_NEIGHBOR_EXCHANGE:
if (!memcmp(dbdesc, &on->dbdesc_last,
sizeof(struct ospf6_dbdesc))) {
@@ -835,8 +866,8 @@ static void ospf6_dbdesc_recv_slave(struct ospf6_header *oh,
"Neighbor state is not ExStart, ignore");
return;
}
- /* else fall through to ExStart */
- /* fallthru */
+ /* else fall through to ExStart */
+ fallthrough;
case OSPF6_NEIGHBOR_EXSTART:
/* If the neighbor is Master, act as Slave. Schedule
negotiation_done
@@ -2239,8 +2270,6 @@ static void ospf6_write(struct event *thread)
void ospf6_hello_send(struct event *thread)
{
struct ospf6_interface *oi;
- struct ospf6_packet *op;
- uint16_t length = OSPF6_HEADER_SIZE;
oi = (struct ospf6_interface *)EVENT_ARG(thread);
@@ -2266,6 +2295,20 @@ void ospf6_hello_send(struct event *thread)
return;
}
+ event_add_timer(master, ospf6_hello_send, oi, oi->hello_interval,
+ &oi->thread_send_hello);
+
+ ospf6_hello_send_addr(oi, NULL);
+}
+
+/* used to send polls for PtP/PtMP too */
+void ospf6_hello_send_addr(struct ospf6_interface *oi,
+ const struct in6_addr *addr)
+{
+ struct ospf6_packet *op;
+ uint16_t length = OSPF6_HEADER_SIZE;
+ bool anything = false;
+
op = ospf6_packet_new(oi->ifmtu);
ospf6_make_header(OSPF6_MESSAGE_TYPE_HELLO, oi, op->s);
@@ -2284,20 +2327,40 @@ void ospf6_hello_send(struct event *thread)
/* Set packet length. */
op->length = length;
- op->dst = allspfrouters6;
-
- ospf6_fill_hdr_checksum(oi, op);
+ if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT
+ || oi->state == OSPF6_INTERFACE_POINTTOMULTIPOINT)
+ && !addr && oi->p2xp_no_multicast_hello) {
+ struct listnode *node;
+ struct ospf6_neighbor *on;
+ struct ospf6_packet *opdup;
+
+ for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, node, on)) {
+ if (on->state < OSPF6_NEIGHBOR_INIT)
+ /* poll-interval for these */
+ continue;
+
+ opdup = ospf6_packet_dup(op);
+ opdup->dst = on->linklocal_addr;
+ ospf6_fill_hdr_checksum(oi, opdup);
+ ospf6_packet_add_top(oi, opdup);
+ anything = true;
+ }
- /* Add packet to the top of the interface output queue, so that they
- * can't get delayed by things like long queues of LS Update packets
- */
- ospf6_packet_add_top(oi, op);
+ ospf6_packet_free(op);
+ } else {
+ op->dst = addr ? *addr : allspfrouters6;
- /* set next thread */
- event_add_timer(master, ospf6_hello_send, oi, oi->hello_interval,
- &oi->thread_send_hello);
+ /* Add packet to the top of the interface output queue, so that
+ * they can't get delayed by things like long queues of LS
+ * Update packets
+ */
+ ospf6_fill_hdr_checksum(oi, op);
+ ospf6_packet_add_top(oi, op);
+ anything = true;
+ }
- OSPF6_MESSAGE_WRITE_ON(oi);
+ if (anything)
+ OSPF6_MESSAGE_WRITE_ON(oi);
}
static uint16_t ospf6_make_dbdesc(struct ospf6_neighbor *on, struct stream *s)
diff --git a/ospf6d/ospf6_message.h b/ospf6d/ospf6_message.h
index 2b25b07..2434079 100644
--- a/ospf6d/ospf6_message.h
+++ b/ospf6d/ospf6_message.h
@@ -50,6 +50,8 @@ extern unsigned char conf_debug_ospf6_message[];
#define OSPF6_MESSAGE_TYPE_ALL 0x6 /* For debug option */
#define OSPF6_MESSAGE_TYPE_MAX 0x6 /* same as OSPF6_MESSAGE_TYPE_ALL */
+struct ospf6_interface;
+
struct ospf6_packet {
struct ospf6_packet *next;
@@ -169,6 +171,9 @@ extern void ospf6_lsupdate_send_neighbor(struct event *thread);
extern void ospf6_lsack_send_interface(struct event *thread);
extern void ospf6_lsack_send_neighbor(struct event *thread);
+extern void ospf6_hello_send_addr(struct ospf6_interface *oi,
+ const struct in6_addr *addr);
+
extern int config_write_ospf6_debug_message(struct vty *);
extern void install_element_ospf6_debug_message(void);
extern const char *ospf6_message_type(int type);
diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c
index e1aec06..a6089b2 100644
--- a/ospf6d/ospf6_neighbor.c
+++ b/ospf6d/ospf6_neighbor.c
@@ -34,6 +34,16 @@
#include "lib/json.h"
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_NEIGHBOR, "OSPF6 neighbor");
+DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_NEIGHBOR_P2XP_CFG,
+ "OSPF6 PtP/PtMP neighbor config");
+
+static int ospf6_if_p2xp_neighcfg_cmp(const struct ospf6_if_p2xp_neighcfg *a,
+ const struct ospf6_if_p2xp_neighcfg *b);
+
+DECLARE_RBTREE_UNIQ(ospf6_if_p2xp_neighcfgs, struct ospf6_if_p2xp_neighcfg,
+ item, ospf6_if_p2xp_neighcfg_cmp);
+
+static void p2xp_neigh_refresh(struct ospf6_neighbor *on, uint32_t prev_cost);
DEFINE_HOOK(ospf6_neighbor_change,
(struct ospf6_neighbor * on, int state, int next_state),
@@ -42,13 +52,14 @@ DEFINE_HOOK(ospf6_neighbor_change,
unsigned char conf_debug_ospf6_neighbor = 0;
const char *const ospf6_neighbor_state_str[] = {
- "None", "Down", "Attempt", "Init", "Twoway",
- "ExStart", "ExChange", "Loading", "Full", NULL};
+ "None", "Down", "Attempt", "Init", "Twoway",
+ "ExStart", "ExChange", "Loading", "Full", NULL
+};
const char *const ospf6_neighbor_event_str[] = {
- "NoEvent", "HelloReceived", "2-WayReceived", "NegotiationDone",
- "ExchangeDone", "LoadingDone", "AdjOK?", "SeqNumberMismatch",
- "BadLSReq", "1-WayReceived", "InactivityTimer",
+ "NoEvent", "HelloReceived", "2-WayReceived", "NegotiationDone",
+ "ExchangeDone", "LoadingDone", "AdjOK?", "SeqNumberMismatch",
+ "BadLSReq", "1-WayReceived", "InactivityTimer",
};
int ospf6_neighbor_cmp(void *va, void *vb)
@@ -119,8 +130,7 @@ struct ospf6_neighbor *ospf6_neighbor_create(uint32_t router_id,
on = XCALLOC(MTYPE_OSPF6_NEIGHBOR, sizeof(struct ospf6_neighbor));
inet_ntop(AF_INET, &router_id, buf, sizeof(buf));
- snprintf(on->name, sizeof(on->name), "%s%%%s", buf,
- oi->interface->name);
+ snprintf(on->name, sizeof(on->name), "%s%%%s", buf, oi->interface->name);
on->ospf6_if = oi;
on->state = OSPF6_NEIGHBOR_DOWN;
on->state_change = 0;
@@ -150,6 +160,9 @@ struct ospf6_neighbor *ospf6_neighbor_create(uint32_t router_id,
void ospf6_neighbor_delete(struct ospf6_neighbor *on)
{
+ if (on->p2xp_cfg)
+ on->p2xp_cfg->active = NULL;
+
ospf6_neighbor_clear_ls_lists(on);
ospf6_lsdb_remove_all(on->dbdesc_list);
@@ -182,6 +195,22 @@ void ospf6_neighbor_delete(struct ospf6_neighbor *on)
XFREE(MTYPE_OSPF6_NEIGHBOR, on);
}
+void ospf6_neighbor_lladdr_set(struct ospf6_neighbor *on,
+ const struct in6_addr *addr)
+{
+ if (IPV6_ADDR_SAME(addr, &on->linklocal_addr))
+ return;
+
+ memcpy(&on->linklocal_addr, addr, sizeof(struct in6_addr));
+
+ if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT ||
+ on->ospf6_if->type == OSPF_IFTYPE_POINTOMULTIPOINT) {
+ uint32_t prev_cost = ospf6_neighbor_cost(on);
+
+ p2xp_neigh_refresh(on, prev_cost);
+ }
+}
+
static void ospf6_neighbor_state_change(uint8_t next_state,
struct ospf6_neighbor *on, int event)
{
@@ -198,31 +227,28 @@ static void ospf6_neighbor_state_change(uint8_t next_state,
/* log */
if (IS_OSPF6_DEBUG_NEIGHBOR(STATE)) {
- zlog_debug(
- "Neighbor state change %s (Router-ID: %pI4): [%s]->[%s] (%s)",
- on->name, &on->router_id,
- ospf6_neighbor_state_str[prev_state],
- ospf6_neighbor_state_str[next_state],
- ospf6_neighbor_event_string(event));
+ zlog_debug("Neighbor state change %s (Router-ID: %pI4): [%s]->[%s] (%s)",
+ on->name, &on->router_id,
+ ospf6_neighbor_state_str[prev_state],
+ ospf6_neighbor_state_str[next_state],
+ ospf6_neighbor_event_string(event));
}
/* Optionally notify about adjacency changes */
if (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags,
- OSPF6_LOG_ADJACENCY_CHANGES)
- && (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags,
- OSPF6_LOG_ADJACENCY_DETAIL)
- || (next_state == OSPF6_NEIGHBOR_FULL)
- || (next_state < prev_state)))
- zlog_notice(
- "AdjChg: Nbr %pI4(%s) on %s: %s -> %s (%s)",
- &on->router_id,
- vrf_id_to_name(on->ospf6_if->interface->vrf->vrf_id),
- on->name, ospf6_neighbor_state_str[prev_state],
- ospf6_neighbor_state_str[next_state],
- ospf6_neighbor_event_string(event));
-
- if (prev_state == OSPF6_NEIGHBOR_FULL
- || next_state == OSPF6_NEIGHBOR_FULL) {
+ OSPF6_LOG_ADJACENCY_CHANGES) &&
+ (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags,
+ OSPF6_LOG_ADJACENCY_DETAIL) ||
+ (next_state == OSPF6_NEIGHBOR_FULL) || (next_state < prev_state)))
+ zlog_notice("AdjChg: Nbr %pI4(%s) on %s: %s -> %s (%s)",
+ &on->router_id,
+ vrf_id_to_name(on->ospf6_if->interface->vrf->vrf_id),
+ on->name, ospf6_neighbor_state_str[prev_state],
+ ospf6_neighbor_state_str[next_state],
+ ospf6_neighbor_event_string(event));
+
+ if (prev_state == OSPF6_NEIGHBOR_FULL ||
+ next_state == OSPF6_NEIGHBOR_FULL) {
if (!OSPF6_GR_IS_ACTIVE_HELPER(on)) {
OSPF6_ROUTER_LSA_SCHEDULE(on->ospf6_if->area);
if (on->ospf6_if->state == OSPF6_INTERFACE_DR) {
@@ -235,12 +261,11 @@ static void ospf6_neighbor_state_change(uint8_t next_state,
on->ospf6_if->area->intra_prefix_originate = 1;
if (!OSPF6_GR_IS_ACTIVE_HELPER(on))
- OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(
- on->ospf6_if->area);
+ OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(on->ospf6_if->area);
- if ((prev_state == OSPF6_NEIGHBOR_LOADING
- || prev_state == OSPF6_NEIGHBOR_EXCHANGE)
- && next_state == OSPF6_NEIGHBOR_FULL) {
+ if ((prev_state == OSPF6_NEIGHBOR_LOADING ||
+ prev_state == OSPF6_NEIGHBOR_EXCHANGE) &&
+ next_state == OSPF6_NEIGHBOR_FULL) {
OSPF6_AS_EXTERN_LSA_SCHEDULE(on->ospf6_if);
on->ospf6_if->area->full_nbrs++;
}
@@ -249,10 +274,10 @@ static void ospf6_neighbor_state_change(uint8_t next_state,
on->ospf6_if->area->full_nbrs--;
}
- if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE
- || prev_state == OSPF6_NEIGHBOR_LOADING)
- && (next_state != OSPF6_NEIGHBOR_EXCHANGE
- && next_state != OSPF6_NEIGHBOR_LOADING))
+ if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE ||
+ prev_state == OSPF6_NEIGHBOR_LOADING) &&
+ (next_state != OSPF6_NEIGHBOR_EXCHANGE &&
+ next_state != OSPF6_NEIGHBOR_LOADING))
ospf6_maxage_remove(on->ospf6_if->area->ospf6);
hook_call(ospf6_neighbor_change, on, next_state, prev_state);
@@ -262,13 +287,14 @@ static void ospf6_neighbor_state_change(uint8_t next_state,
/* RFC2328 section 10.4 */
static int need_adjacency(struct ospf6_neighbor *on)
{
- if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT
- || on->ospf6_if->state == OSPF6_INTERFACE_DR
- || on->ospf6_if->state == OSPF6_INTERFACE_BDR)
+ if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT ||
+ on->ospf6_if->state == OSPF6_INTERFACE_POINTTOMULTIPOINT ||
+ on->ospf6_if->state == OSPF6_INTERFACE_DR ||
+ on->ospf6_if->state == OSPF6_INTERFACE_BDR)
return 1;
- if (on->ospf6_if->drouter == on->router_id
- || on->ospf6_if->bdrouter == on->router_id)
+ if (on->ospf6_if->drouter == on->router_id ||
+ on->ospf6_if->bdrouter == on->router_id)
return 1;
return 0;
@@ -422,13 +448,12 @@ void exchange_done(struct event *thread)
/* Check loading state. */
void ospf6_check_nbr_loading(struct ospf6_neighbor *on)
{
-
/* RFC2328 Section 10.9: When the neighbor responds to these requests
with the proper Link State Update packet(s), the Link state request
list is truncated and a new Link State Request packet is sent.
*/
- if ((on->state == OSPF6_NEIGHBOR_LOADING)
- || (on->state == OSPF6_NEIGHBOR_EXCHANGE)) {
+ if ((on->state == OSPF6_NEIGHBOR_LOADING) ||
+ (on->state == OSPF6_NEIGHBOR_EXCHANGE)) {
if (on->request_list->count == 0)
event_add_event(master, loading_done, on, 0,
&on->event_loading_done);
@@ -587,9 +612,8 @@ void inactivity_timer(struct event *thread)
on->drouter = on->prev_drouter = 0;
on->bdrouter = on->prev_bdrouter = 0;
- ospf6_neighbor_state_change(
- OSPF6_NEIGHBOR_DOWN, on,
- OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER);
+ ospf6_neighbor_state_change(OSPF6_NEIGHBOR_DOWN, on,
+ OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER);
event_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
listnode_delete(on->ospf6_if->neighbor_list, on);
@@ -597,9 +621,8 @@ void inactivity_timer(struct event *thread)
} else {
if (IS_DEBUG_OSPF6_GR)
- zlog_debug(
- "%s, Acting as HELPER for this neighbour, So restart the dead timer.",
- __PRETTY_FUNCTION__);
+ zlog_debug("%s, Acting as HELPER for this neighbour, So restart the dead timer.",
+ __PRETTY_FUNCTION__);
event_add_timer(master, inactivity_timer, on,
on->ospf6_if->dead_interval,
@@ -607,8 +630,224 @@ void inactivity_timer(struct event *thread)
}
}
+/* P2P/P2MP stuff */
+
+uint32_t ospf6_neighbor_cost(struct ospf6_neighbor *on)
+{
+ if (on->p2xp_cfg && on->p2xp_cfg->cfg_cost)
+ return on->p2xp_cfg->cost;
+ return on->ospf6_if->cost;
+}
+
+static int ospf6_if_p2xp_neighcfg_cmp(const struct ospf6_if_p2xp_neighcfg *a,
+ const struct ospf6_if_p2xp_neighcfg *b)
+{
+ return IPV6_ADDR_CMP(&a->addr, &b->addr);
+}
+
+struct ospf6_if_p2xp_neighcfg *ospf6_if_p2xp_find(struct ospf6_interface *oi,
+ const struct in6_addr *addr)
+{
+ struct ospf6_if_p2xp_neighcfg ref;
+
+ if (!oi)
+ return NULL;
+
+ ref.addr = *addr;
+ return ospf6_if_p2xp_neighcfgs_find(&oi->p2xp_neighs, &ref);
+}
+
+static struct ospf6_if_p2xp_neighcfg *
+ospf6_if_p2xp_get(struct ospf6_interface *oi, const struct in6_addr *addr)
+{
+ struct ospf6_if_p2xp_neighcfg ref, *ret;
+
+ if (!oi)
+ return NULL;
+
+ ref.addr = *addr;
+ ret = ospf6_if_p2xp_neighcfgs_find(&oi->p2xp_neighs, &ref);
+ if (!ret) {
+ ret = XCALLOC(MTYPE_OSPF6_NEIGHBOR_P2XP_CFG, sizeof(*ret));
+ ret->addr = *addr;
+ ret->ospf6_if = oi;
+
+ ospf6_if_p2xp_neighcfgs_add(&oi->p2xp_neighs, ret);
+ }
+
+ return ret;
+}
+
+static void ospf6_if_p2xp_destroy(struct ospf6_if_p2xp_neighcfg *p2xp_cfg)
+{
+ EVENT_OFF(p2xp_cfg->t_unicast_hello);
+ ospf6_if_p2xp_neighcfgs_del(&p2xp_cfg->ospf6_if->p2xp_neighs, p2xp_cfg);
+
+ XFREE(MTYPE_OSPF6_NEIGHBOR_P2XP_CFG, p2xp_cfg);
+}
+
+static void p2xp_neigh_refresh(struct ospf6_neighbor *on, uint32_t prev_cost)
+{
+ if (on->p2xp_cfg)
+ on->p2xp_cfg->active = NULL;
+ on->p2xp_cfg = ospf6_if_p2xp_find(on->ospf6_if, &on->linklocal_addr);
+ if (on->p2xp_cfg)
+ on->p2xp_cfg->active = on;
+
+ if (ospf6_neighbor_cost(on) != prev_cost)
+ OSPF6_ROUTER_LSA_SCHEDULE(on->ospf6_if->area);
+}
/* vty functions */
+
+#ifndef VTYSH_EXTRACT_PL
+#include "ospf6d/ospf6_neighbor_clippy.c"
+#endif
+
+DEFPY(ipv6_ospf6_p2xp_neigh, ipv6_ospf6_p2xp_neigh_cmd,
+ "[no] ipv6 ospf6 neighbor X:X::X:X",
+ NO_STR IP6_STR OSPF6_STR "Configure static neighbor\n"
+ "Neighbor link-local address\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct ospf6_interface *oi = ifp->info;
+ struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
+
+ if (!oi) {
+ if (no)
+ return CMD_SUCCESS;
+ oi = ospf6_interface_create(ifp);
+ }
+
+ if (no) {
+ struct ospf6_neighbor *on;
+ uint32_t prev_cost = 0;
+
+ p2xp_cfg = ospf6_if_p2xp_find(oi, &neighbor);
+ if (!p2xp_cfg)
+ return CMD_SUCCESS;
+
+ on = p2xp_cfg->active;
+ if (on)
+ prev_cost = ospf6_neighbor_cost(on);
+
+ p2xp_cfg->active = NULL;
+ ospf6_if_p2xp_destroy(p2xp_cfg);
+
+ if (on) {
+ on->p2xp_cfg = NULL;
+ p2xp_neigh_refresh(on, prev_cost);
+ }
+ return CMD_SUCCESS;
+ }
+
+ (void)ospf6_if_p2xp_get(oi, &neighbor);
+ return CMD_SUCCESS;
+}
+
+DEFPY(ipv6_ospf6_p2xp_neigh_cost, ipv6_ospf6_p2xp_neigh_cost_cmd,
+ "[no] ipv6 ospf6 neighbor X:X::X:X cost (1-65535)",
+ NO_STR IP6_STR OSPF6_STR "Configure static neighbor\n"
+ "Neighbor link-local address\n"
+ "Outgoing metric for this neighbor\n"
+ "Outgoing metric for this neighbor\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct ospf6_interface *oi = ifp->info;
+ struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
+ uint32_t prev_cost = 0;
+
+ if (!oi) {
+ if (no)
+ return CMD_SUCCESS;
+ oi = ospf6_interface_create(ifp);
+ }
+
+ p2xp_cfg = ospf6_if_p2xp_get(oi, &neighbor);
+
+ if (p2xp_cfg->active)
+ prev_cost = ospf6_neighbor_cost(p2xp_cfg->active);
+
+ if (no) {
+ p2xp_cfg->cfg_cost = false;
+ p2xp_cfg->cost = 0;
+ } else {
+ p2xp_cfg->cfg_cost = true;
+ p2xp_cfg->cost = cost;
+ }
+
+ if (p2xp_cfg->active)
+ p2xp_neigh_refresh(p2xp_cfg->active, prev_cost);
+ return CMD_SUCCESS;
+}
+
+static void p2xp_unicast_hello_send(struct event *event);
+
+static void p2xp_unicast_hello_sched(struct ospf6_if_p2xp_neighcfg *p2xp_cfg)
+{
+ if (!p2xp_cfg->poll_interval ||
+ (p2xp_cfg->ospf6_if->state != OSPF6_INTERFACE_POINTTOMULTIPOINT &&
+ p2xp_cfg->ospf6_if->state != OSPF6_INTERFACE_POINTTOPOINT))
+ /* state check covers DOWN state too */
+ EVENT_OFF(p2xp_cfg->t_unicast_hello);
+ else
+ event_add_timer(master, p2xp_unicast_hello_send, p2xp_cfg,
+ p2xp_cfg->poll_interval,
+ &p2xp_cfg->t_unicast_hello);
+}
+
+void ospf6_if_p2xp_up(struct ospf6_interface *oi)
+{
+ struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
+
+ frr_each (ospf6_if_p2xp_neighcfgs, &oi->p2xp_neighs, p2xp_cfg)
+ p2xp_unicast_hello_sched(p2xp_cfg);
+}
+
+static void p2xp_unicast_hello_send(struct event *event)
+{
+ struct ospf6_if_p2xp_neighcfg *p2xp_cfg = EVENT_ARG(event);
+ struct ospf6_interface *oi = p2xp_cfg->ospf6_if;
+
+ if (oi->state != OSPF6_INTERFACE_POINTTOPOINT &&
+ oi->state != OSPF6_INTERFACE_POINTTOMULTIPOINT)
+ return;
+
+ p2xp_unicast_hello_sched(p2xp_cfg);
+
+ if (p2xp_cfg->active && p2xp_cfg->active->state >= OSPF6_NEIGHBOR_INIT)
+ return;
+
+ ospf6_hello_send_addr(oi, &p2xp_cfg->addr);
+}
+
+DEFPY(ipv6_ospf6_p2xp_neigh_poll_interval,
+ ipv6_ospf6_p2xp_neigh_poll_interval_cmd,
+ "[no] ipv6 ospf6 neighbor X:X::X:X poll-interval (1-65535)",
+ NO_STR IP6_STR OSPF6_STR "Configure static neighbor\n"
+ "Neighbor link-local address\n"
+ "Send unicast hellos to neighbor when down\n"
+ "Unicast hello interval when down (seconds)\n")
+{
+ VTY_DECLVAR_CONTEXT(interface, ifp);
+ struct ospf6_interface *oi = ifp->info;
+ struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
+
+ if (!oi) {
+ if (no)
+ return CMD_SUCCESS;
+ oi = ospf6_interface_create(ifp);
+ }
+ if (no)
+ poll_interval = 0;
+
+ p2xp_cfg = ospf6_if_p2xp_get(oi, &neighbor);
+ p2xp_cfg->poll_interval = poll_interval;
+
+ p2xp_unicast_hello_sched(p2xp_cfg);
+ return CMD_SUCCESS;
+}
+
/* show neighbor structure */
static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on,
json_object *json_array, bool use_json)
@@ -631,8 +870,8 @@ static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on,
/* Dead time */
h = m = s = 0;
if (on->inactivity_timer) {
- s = monotime_until(&on->inactivity_timer->u.sands, NULL)
- / 1000000LL;
+ s = monotime_until(&on->inactivity_timer->u.sands, NULL) /
+ 1000000LL;
h = s / 3600;
s -= h * 3600;
m = s / 60;
@@ -643,6 +882,8 @@ static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on,
/* Neighbor State */
if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT)
snprintf(nstate, sizeof(nstate), "PointToPoint");
+ else if (on->ospf6_if->type == OSPF_IFTYPE_POINTOMULTIPOINT)
+ snprintf(nstate, sizeof(nstate), "PtMultipoint");
else {
if (on->router_id == on->drouter)
snprintf(nstate, sizeof(nstate), "DR");
@@ -673,9 +914,9 @@ static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on,
json_object_string_add(json_route, "duration", duration);
json_object_string_add(json_route, "interfaceName",
on->ospf6_if->interface->name);
- json_object_string_add(
- json_route, "interfaceState",
- ospf6_interface_state_str[on->ospf6_if->state]);
+ json_object_string_add(json_route, "interfaceState",
+ ospf6_interface_state_str
+ [on->ospf6_if->state]);
json_object_array_add(json_array, json_route);
} else
@@ -720,9 +961,9 @@ static void ospf6_neighbor_show_drchoice(struct vty *vty,
json_object_string_add(json_route, "bdRouter", bdrouter);
json_object_string_add(json_route, "interfaceName",
on->ospf6_if->interface->name);
- json_object_string_add(
- json_route, "interfaceState",
- ospf6_interface_state_str[on->ospf6_if->state]);
+ json_object_string_add(json_route, "interfaceState",
+ ospf6_interface_state_str
+ [on->ospf6_if->state]);
json_object_array_add(json_array, json_route);
} else
@@ -777,9 +1018,8 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
(CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT)
? "Initial "
: ""),
- (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT)
- ? "More"
- : ""),
+ (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT) ? "More"
+ : ""),
(CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT)
? "Master"
: "Slave"));
@@ -793,8 +1033,8 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
json_object_int_add(json_neighbor, "summaryListCount",
on->summary_list->count);
for (ALL_LSDB(on->summary_list, lsa, lsanext))
- json_object_array_add(
- json_array, json_object_new_string(lsa->name));
+ json_object_array_add(json_array,
+ json_object_new_string(lsa->name));
json_object_object_add(json_neighbor, "summaryListLsa",
json_array);
@@ -802,8 +1042,8 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
json_object_int_add(json_neighbor, "requestListCount",
on->request_list->count);
for (ALL_LSDB(on->request_list, lsa, lsanext))
- json_object_array_add(
- json_array, json_object_new_string(lsa->name));
+ json_object_array_add(json_array,
+ json_object_new_string(lsa->name));
json_object_object_add(json_neighbor, "requestListLsa",
json_array);
@@ -811,8 +1051,8 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
json_object_int_add(json_neighbor, "reTransListCount",
on->retrans_list->count);
for (ALL_LSDB(on->retrans_list, lsa, lsanext))
- json_object_array_add(
- json_array, json_object_new_string(lsa->name));
+ json_object_array_add(json_array,
+ json_object_new_string(lsa->name));
json_object_object_add(json_neighbor, "reTransListLsa",
json_array);
@@ -825,14 +1065,14 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
on->dbdesc_list->count);
json_object_string_add(json_neighbor, "pendingLsaDbDescTime",
duration);
- json_object_string_add(
- json_neighbor, "dbDescSendThread",
- (event_is_scheduled(on->thread_send_dbdesc) ? "on"
- : "off"));
+ json_object_string_add(json_neighbor, "dbDescSendThread",
+ (event_is_scheduled(on->thread_send_dbdesc)
+ ? "on"
+ : "off"));
json_array = json_object_new_array();
for (ALL_LSDB(on->dbdesc_list, lsa, lsanext))
- json_object_array_add(
- json_array, json_object_new_string(lsa->name));
+ json_object_array_add(json_array,
+ json_object_new_string(lsa->name));
json_object_object_add(json_neighbor, "pendingLsaDbDesc",
json_array);
@@ -844,35 +1084,35 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
on->request_list->count);
json_object_string_add(json_neighbor, "pendingLsaLsReqTime",
duration);
- json_object_string_add(
- json_neighbor, "lsReqSendThread",
- (event_is_scheduled(on->thread_send_lsreq) ? "on"
- : "off"));
+ json_object_string_add(json_neighbor, "lsReqSendThread",
+ (event_is_scheduled(on->thread_send_lsreq)
+ ? "on"
+ : "off"));
json_array = json_object_new_array();
for (ALL_LSDB(on->request_list, lsa, lsanext))
- json_object_array_add(
- json_array, json_object_new_string(lsa->name));
+ json_object_array_add(json_array,
+ json_object_new_string(lsa->name));
json_object_object_add(json_neighbor, "pendingLsaLsReq",
json_array);
timerclear(&res);
if (event_is_scheduled(on->thread_send_lsupdate))
- timersub(&on->thread_send_lsupdate->u.sands, &now,
- &res);
+ timersub(&on->thread_send_lsupdate->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
json_object_int_add(json_neighbor, "pendingLsaLsUpdateCount",
on->lsupdate_list->count);
json_object_string_add(json_neighbor, "pendingLsaLsUpdateTime",
duration);
- json_object_string_add(
- json_neighbor, "lsUpdateSendThread",
- (event_is_scheduled(on->thread_send_lsupdate) ? "on"
- : "off"));
+ json_object_string_add(json_neighbor, "lsUpdateSendThread",
+ (event_is_scheduled(
+ on->thread_send_lsupdate)
+ ? "on"
+ : "off"));
json_array = json_object_new_array();
for (ALL_LSDB(on->lsupdate_list, lsa, lsanext))
- json_object_array_add(
- json_array, json_object_new_string(lsa->name));
+ json_object_array_add(json_array,
+ json_object_new_string(lsa->name));
json_object_object_add(json_neighbor, "pendingLsaLsUpdate",
json_array);
@@ -884,14 +1124,14 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
on->lsack_list->count);
json_object_string_add(json_neighbor, "pendingLsaLsAckTime",
duration);
- json_object_string_add(
- json_neighbor, "lsAckSendThread",
- (event_is_scheduled(on->thread_send_lsack) ? "on"
- : "off"));
+ json_object_string_add(json_neighbor, "lsAckSendThread",
+ (event_is_scheduled(on->thread_send_lsack)
+ ? "on"
+ : "off"));
json_array = json_object_new_array();
for (ALL_LSDB(on->lsack_list, lsa, lsanext))
- json_object_array_add(
- json_array, json_object_new_string(lsa->name));
+ json_object_array_add(json_array,
+ json_object_new_string(lsa->name));
json_object_object_add(json_neighbor, "pendingLsaLsAck",
json_array);
@@ -900,36 +1140,36 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
if (on->auth_present == true) {
json_object_string_add(json_neighbor, "authStatus",
"enabled");
- json_object_int_add(
- json_neighbor, "recvdHelloHigherSeqNo",
- on->seqnum_h[OSPF6_MESSAGE_TYPE_HELLO]);
- json_object_int_add(
- json_neighbor, "recvdHelloLowerSeqNo",
- on->seqnum_l[OSPF6_MESSAGE_TYPE_HELLO]);
- json_object_int_add(
- json_neighbor, "recvdDBDescHigherSeqNo",
- on->seqnum_h[OSPF6_MESSAGE_TYPE_DBDESC]);
- json_object_int_add(
- json_neighbor, "recvdDBDescLowerSeqNo",
- on->seqnum_l[OSPF6_MESSAGE_TYPE_DBDESC]);
- json_object_int_add(
- json_neighbor, "recvdLSReqHigherSeqNo",
- on->seqnum_h[OSPF6_MESSAGE_TYPE_LSREQ]);
- json_object_int_add(
- json_neighbor, "recvdLSReqLowerSeqNo",
- on->seqnum_l[OSPF6_MESSAGE_TYPE_LSREQ]);
- json_object_int_add(
- json_neighbor, "recvdLSUpdHigherSeqNo",
- on->seqnum_h[OSPF6_MESSAGE_TYPE_LSUPDATE]);
- json_object_int_add(
- json_neighbor, "recvdLSUpdLowerSeqNo",
- on->seqnum_l[OSPF6_MESSAGE_TYPE_LSUPDATE]);
- json_object_int_add(
- json_neighbor, "recvdLSAckHigherSeqNo",
- on->seqnum_h[OSPF6_MESSAGE_TYPE_LSACK]);
- json_object_int_add(
- json_neighbor, "recvdLSAckLowerSeqNo",
- on->seqnum_l[OSPF6_MESSAGE_TYPE_LSACK]);
+ json_object_int_add(json_neighbor,
+ "recvdHelloHigherSeqNo",
+ on->seqnum_h[OSPF6_MESSAGE_TYPE_HELLO]);
+ json_object_int_add(json_neighbor,
+ "recvdHelloLowerSeqNo",
+ on->seqnum_l[OSPF6_MESSAGE_TYPE_HELLO]);
+ json_object_int_add(json_neighbor,
+ "recvdDBDescHigherSeqNo",
+ on->seqnum_h[OSPF6_MESSAGE_TYPE_DBDESC]);
+ json_object_int_add(json_neighbor,
+ "recvdDBDescLowerSeqNo",
+ on->seqnum_l[OSPF6_MESSAGE_TYPE_DBDESC]);
+ json_object_int_add(json_neighbor,
+ "recvdLSReqHigherSeqNo",
+ on->seqnum_h[OSPF6_MESSAGE_TYPE_LSREQ]);
+ json_object_int_add(json_neighbor,
+ "recvdLSReqLowerSeqNo",
+ on->seqnum_l[OSPF6_MESSAGE_TYPE_LSREQ]);
+ json_object_int_add(json_neighbor,
+ "recvdLSUpdHigherSeqNo",
+ on->seqnum_h[OSPF6_MESSAGE_TYPE_LSUPDATE]);
+ json_object_int_add(json_neighbor,
+ "recvdLSUpdLowerSeqNo",
+ on->seqnum_l[OSPF6_MESSAGE_TYPE_LSUPDATE]);
+ json_object_int_add(json_neighbor,
+ "recvdLSAckHigherSeqNo",
+ on->seqnum_h[OSPF6_MESSAGE_TYPE_LSACK]);
+ json_object_int_add(json_neighbor,
+ "recvdLSAckLowerSeqNo",
+ on->seqnum_l[OSPF6_MESSAGE_TYPE_LSACK]);
} else
json_object_string_add(json_neighbor, "authStatus",
"disabled");
@@ -951,9 +1191,8 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
(CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT)
? "Initial "
: ""),
- (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT)
- ? "More "
- : ""),
+ (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT) ? "More "
+ : ""),
(CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT)
? "Master"
: "Slave"),
@@ -1000,8 +1239,7 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
timerclear(&res);
if (event_is_scheduled(on->thread_send_lsupdate))
- timersub(&on->thread_send_lsupdate->u.sands, &now,
- &res);
+ timersub(&on->thread_send_lsupdate->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
vty_out(vty,
" %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
@@ -1141,8 +1379,7 @@ DEFUN(show_ipv6_ospf6_neighbor, show_ipv6_ospf6_neighbor_cmd,
static int ospf6_neighbor_show_common(struct vty *vty, int argc,
struct cmd_token **argv,
- struct ospf6 *ospf6, int idx_ipv4,
- bool uj)
+ struct ospf6 *ospf6, int idx_ipv4, bool uj)
{
struct ospf6_neighbor *on;
struct ospf6_interface *oi;
@@ -1214,16 +1451,18 @@ void ospf6_neighbor_init(void)
{
install_element(VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
install_element(VIEW_NODE, &show_ipv6_ospf6_neighbor_one_cmd);
+
+ install_element(INTERFACE_NODE, &ipv6_ospf6_p2xp_neigh_cmd);
+ install_element(INTERFACE_NODE, &ipv6_ospf6_p2xp_neigh_cost_cmd);
+ install_element(INTERFACE_NODE,
+ &ipv6_ospf6_p2xp_neigh_poll_interval_cmd);
}
-DEFUN (debug_ospf6_neighbor,
- debug_ospf6_neighbor_cmd,
- "debug ospf6 neighbor [<state|event>]",
- DEBUG_STR
- OSPF6_STR
- "Debug OSPFv3 Neighbor\n"
- "Debug OSPFv3 Neighbor State Change\n"
- "Debug OSPFv3 Neighbor Event\n")
+DEFUN(debug_ospf6_neighbor, debug_ospf6_neighbor_cmd,
+ "debug ospf6 neighbor [<state|event>]",
+ DEBUG_STR OSPF6_STR "Debug OSPFv3 Neighbor\n"
+ "Debug OSPFv3 Neighbor State Change\n"
+ "Debug OSPFv3 Neighbor Event\n")
{
int idx_type = 3;
unsigned char level = 0;
@@ -1241,15 +1480,11 @@ DEFUN (debug_ospf6_neighbor,
}
-DEFUN (no_debug_ospf6_neighbor,
- no_debug_ospf6_neighbor_cmd,
- "no debug ospf6 neighbor [<state|event>]",
- NO_STR
- DEBUG_STR
- OSPF6_STR
- "Debug OSPFv3 Neighbor\n"
- "Debug OSPFv3 Neighbor State Change\n"
- "Debug OSPFv3 Neighbor Event\n")
+DEFUN(no_debug_ospf6_neighbor, no_debug_ospf6_neighbor_cmd,
+ "no debug ospf6 neighbor [<state|event>]",
+ NO_STR DEBUG_STR OSPF6_STR "Debug OSPFv3 Neighbor\n"
+ "Debug OSPFv3 Neighbor State Change\n"
+ "Debug OSPFv3 Neighbor Event\n")
{
int idx_type = 4;
unsigned char level = 0;
@@ -1267,12 +1502,8 @@ DEFUN (no_debug_ospf6_neighbor,
}
-DEFUN (no_debug_ospf6,
- no_debug_ospf6_cmd,
- "no debug ospf6",
- NO_STR
- DEBUG_STR
- OSPF6_STR)
+DEFUN(no_debug_ospf6, no_debug_ospf6_cmd, "no debug ospf6",
+ NO_STR DEBUG_STR OSPF6_STR)
{
unsigned int i;
@@ -1287,12 +1518,11 @@ DEFUN (no_debug_ospf6,
ospf6_lsa_debug_set_all(false);
for (i = 0; i < 6; i++)
- OSPF6_DEBUG_MESSAGE_OFF(i,
- OSPF6_DEBUG_NEIGHBOR_STATE
- | OSPF6_DEBUG_NEIGHBOR_EVENT);
+ OSPF6_DEBUG_MESSAGE_OFF(i, OSPF6_DEBUG_NEIGHBOR_STATE |
+ OSPF6_DEBUG_NEIGHBOR_EVENT);
- OSPF6_DEBUG_NEIGHBOR_OFF(OSPF6_DEBUG_NEIGHBOR_STATE
- | OSPF6_DEBUG_NEIGHBOR_EVENT);
+ OSPF6_DEBUG_NEIGHBOR_OFF(OSPF6_DEBUG_NEIGHBOR_STATE |
+ OSPF6_DEBUG_NEIGHBOR_EVENT);
OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_TABLE);
OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_INTRA);
OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_INTER);
@@ -1316,6 +1546,25 @@ int config_write_ospf6_debug_neighbor(struct vty *vty)
return 0;
}
+int config_write_ospf6_p2xp_neighbor(struct vty *vty, struct ospf6_interface *oi)
+{
+ struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
+
+ frr_each (ospf6_if_p2xp_neighcfgs, &oi->p2xp_neighs, p2xp_cfg) {
+ vty_out(vty, " ipv6 ospf6 neighbor %pI6\n", &p2xp_cfg->addr);
+
+ if (p2xp_cfg->poll_interval)
+ vty_out(vty,
+ " ipv6 ospf6 neighbor %pI6 poll-interval %u\n",
+ &p2xp_cfg->addr, p2xp_cfg->poll_interval);
+
+ if (p2xp_cfg->cfg_cost)
+ vty_out(vty, " ipv6 ospf6 neighbor %pI6 cost %u\n",
+ &p2xp_cfg->addr, p2xp_cfg->cost);
+ }
+ return 0;
+}
+
void install_element_ospf6_debug_neighbor(void)
{
install_element(ENABLE_NODE, &debug_ospf6_neighbor_cmd);
diff --git a/ospf6d/ospf6_neighbor.h b/ospf6d/ospf6_neighbor.h
index 226f4c1..60a7621 100644
--- a/ospf6d/ospf6_neighbor.h
+++ b/ospf6d/ospf6_neighbor.h
@@ -6,8 +6,11 @@
#ifndef OSPF6_NEIGHBOR_H
#define OSPF6_NEIGHBOR_H
+#include "typesafe.h"
#include "hook.h"
+#include "ospf6_message.h"
+
/* Forward declaration(s). */
struct ospf6_area;
@@ -52,6 +55,8 @@ struct ospf6_helper_info {
uint32_t rejected_reason;
};
+struct ospf6_if_p2xp_neighcfg;
+
/* Neighbor structure */
struct ospf6_neighbor {
/* Neighbor Router ID String */
@@ -60,6 +65,11 @@ struct ospf6_neighbor {
/* OSPFv3 Interface this neighbor belongs to */
struct ospf6_interface *ospf6_if;
+ /* P2P/P2MP config for this neighbor.
+ * can be NULL if not explicitly configured!
+ */
+ struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
+
/* Neighbor state */
uint8_t state;
@@ -190,6 +200,14 @@ struct ospf6_neighbor *ospf6_neighbor_create(uint32_t router_id,
struct ospf6_interface *oi);
void ospf6_neighbor_delete(struct ospf6_neighbor *on);
+void ospf6_neighbor_lladdr_set(struct ospf6_neighbor *on,
+ const struct in6_addr *addr);
+struct ospf6_if_p2xp_neighcfg *ospf6_if_p2xp_find(struct ospf6_interface *oi,
+ const struct in6_addr *addr);
+void ospf6_if_p2xp_up(struct ospf6_interface *oi);
+
+uint32_t ospf6_neighbor_cost(struct ospf6_neighbor *on);
+
/* Neighbor event */
extern void hello_received(struct event *thread);
extern void twoway_received(struct event *thread);
@@ -205,6 +223,8 @@ extern void ospf6_check_nbr_loading(struct ospf6_neighbor *on);
extern void ospf6_neighbor_init(void);
extern int config_write_ospf6_debug_neighbor(struct vty *vty);
+extern int config_write_ospf6_p2xp_neighbor(struct vty *vty,
+ struct ospf6_interface *oi);
extern void install_element_ospf6_debug_neighbor(void);
DECLARE_HOOK(ospf6_neighbor_change,
diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c
index 4430329..10a1208 100644
--- a/ospf6d/ospf6_route.c
+++ b/ospf6d/ospf6_route.c
@@ -363,7 +363,7 @@ void ospf6_route_zebra_copy_nexthops(struct ospf6_route *route,
case NEXTHOP_TYPE_IPV6_IFINDEX:
nexthops[i].ifindex = nh->ifindex;
- /* FALLTHROUGH */
+ fallthrough;
case NEXTHOP_TYPE_IPV6:
nexthops[i].gate.ipv6 = nh->address;
break;
@@ -540,6 +540,10 @@ int ospf6_route_cmp(struct ospf6_route *ra, struct ospf6_route *rb)
if (ra->path.area_id != rb->path.area_id)
return (ntohl(ra->path.area_id) - ntohl(rb->path.area_id));
+ if ((ra->prefix_options & OSPF6_PREFIX_OPTION_LA)
+ != (rb->prefix_options & OSPF6_PREFIX_OPTION_LA))
+ return ra->prefix_options & OSPF6_PREFIX_OPTION_LA ? -1 : 1;
+
return 0;
}
diff --git a/ospf6d/ospf6_route.h b/ospf6d/ospf6_route.h
index c212595..2c1d17e 100644
--- a/ospf6d/ospf6_route.h
+++ b/ospf6d/ospf6_route.h
@@ -67,7 +67,7 @@ static inline bool ospf6_nexthop_is_same(const struct ospf6_nexthop *nha,
case NEXTHOP_TYPE_IPV6_IFINDEX:
if (nha->ifindex != nhb->ifindex)
return false;
- /* FALLTHROUGH */
+ fallthrough;
case NEXTHOP_TYPE_IPV6:
if (!IN6_ARE_ADDR_EQUAL(&nha->address, &nhb->address))
return false;
diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c
index f88667b..17cdcda 100644
--- a/ospf6d/ospf6_snmp.c
+++ b/ospf6d/ospf6_snmp.c
@@ -697,8 +697,8 @@ static uint8_t *ospfv3GeneralGroup(struct variable *v, oid *name,
case OSPFv3REFERENCEBANDWIDTH:
if (ospf6)
return SNMP_INTEGER(ospf6->ref_bandwidth);
- /* Otherwise, like for "not implemented". */
- /* fallthru */
+ /* Otherwise, like for "not implemented". */
+ return NULL;
case OSPFv3RESTARTSUPPORT:
case OSPFv3RESTARTINTERVAL:
case OSPFv3RESTARTSTRICTLSACHECKING:
@@ -1126,6 +1126,8 @@ static uint8_t *ospfv3IfEntry(struct variable *v, oid *name, size_t *length,
return SNMP_INTEGER(1);
else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
return SNMP_INTEGER(3);
+ else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
+ return SNMP_INTEGER(5);
else
break; /* Unknown, don't put anything */
case OSPFv3IFADMINSTATUS:
@@ -1367,6 +1369,7 @@ static int ospf6TrapIfStateChange(struct ospf6_interface *oi, int next_state,
/* Terminal state or regression */
if ((next_state != OSPF6_INTERFACE_POINTTOPOINT)
+ && (next_state != OSPF6_INTERFACE_POINTTOMULTIPOINT)
&& (next_state != OSPF6_INTERFACE_DROTHER)
&& (next_state != OSPF6_INTERFACE_BDR)
&& (next_state != OSPF6_INTERFACE_DR) && (next_state >= prev_state))
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c
index 216837d..a3fb205 100644
--- a/ospf6d/ospf6_top.c
+++ b/ospf6d/ospf6_top.c
@@ -16,6 +16,7 @@
#include "defaults.h"
#include "lib/json.h"
#include "lib_errors.h"
+#include "frrdistance.h"
#include "ospf6_proto.h"
#include "ospf6_message.h"
@@ -429,17 +430,7 @@ static struct ospf6 *ospf6_create(const char *name)
/* Make ospf protocol socket. */
ospf6_serv_sock(o);
- /* If sequence number is stored in persistent storage, read it.
- */
- if (ospf6_auth_nvm_file_exist() == OSPF6_AUTH_FILE_EXIST) {
- ospf6_auth_seqno_nvm_read(o);
- o->seqnum_h = o->seqnum_h + 1;
- ospf6_auth_seqno_nvm_update(o);
- } else {
- o->seqnum_l = o->seqnum_h = 0;
- ospf6_auth_seqno_nvm_update(o);
- }
-
+ ospf6_auth_init(o);
return o;
}
@@ -485,6 +476,7 @@ void ospf6_delete(struct ospf6 *o)
struct ospf6_area *oa;
struct vrf *vrf;
struct ospf6_external_aggr_rt *aggr;
+ uint32_t i;
QOBJ_UNREG(o);
@@ -531,6 +523,13 @@ void ospf6_delete(struct ospf6 *o)
}
route_table_finish(o->rt_aggr_tbl);
+ for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) {
+ if (!o->redist[i])
+ continue;
+
+ list_delete(&o->redist[i]);
+ }
+
XFREE(MTYPE_OSPF6_TOP, o->name);
XFREE(MTYPE_OSPF6_TOP, o);
}
@@ -575,6 +574,11 @@ void ospf6_master_init(struct event_loop *master)
om6->master = master;
}
+void ospf6_master_delete(void)
+{
+ list_delete(&om6->ospf6);
+}
+
static void ospf6_maxage_remover(struct event *thread)
{
struct ospf6 *o = (struct ospf6 *)EVENT_ARG(thread);
@@ -1056,148 +1060,6 @@ DEFUN (no_ospf6_distance_ospf6,
return CMD_SUCCESS;
}
-DEFUN_HIDDEN (ospf6_interface_area,
- ospf6_interface_area_cmd,
- "interface IFNAME area <A.B.C.D|(0-4294967295)>",
- "Enable routing on an IPv6 interface\n"
- IFNAME_STR
- "Specify the OSPF6 area ID\n"
- "OSPF6 area ID in IPv4 address notation\n"
- "OSPF6 area ID in decimal notation\n"
- )
-{
- VTY_DECLVAR_CONTEXT(ospf6, ospf6);
- int idx_ifname = 1;
- int idx_ipv4 = 3;
- struct ospf6_area *oa;
- struct ospf6_interface *oi;
- struct interface *ifp;
- uint32_t area_id;
- int format;
-
- vty_out(vty,
- "This command is deprecated, because it is not VRF-aware.\n");
- vty_out(vty,
- "Please, use \"ipv6 ospf6 area\" on an interface instead.\n");
-
- /* find/create ospf6 interface */
- ifp = if_get_by_name(argv[idx_ifname]->arg, ospf6->vrf_id, ospf6->name);
- oi = (struct ospf6_interface *)ifp->info;
- if (oi == NULL)
- oi = ospf6_interface_create(ifp);
- if (oi->area) {
- vty_out(vty, "%s already attached to Area %s\n",
- oi->interface->name, oi->area->name);
- return CMD_SUCCESS;
- }
-
- if (str2area_id(argv[idx_ipv4]->arg, &area_id, &format)) {
- vty_out(vty, "Malformed Area-ID: %s\n", argv[idx_ipv4]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- oi->area_id = area_id;
- oi->area_id_format = format;
-
- oa = ospf6_area_lookup(area_id, ospf6);
- if (oa == NULL)
- oa = ospf6_area_create(area_id, ospf6, format);
-
- /* attach interface to area */
- listnode_add(oa->if_list, oi); /* sort ?? */
- oi->area = oa;
-
- SET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
-
- /* ospf6 process is currently disabled, not much more to do */
- if (CHECK_FLAG(ospf6->flag, OSPF6_DISABLED))
- return CMD_SUCCESS;
-
- /* start up */
- ospf6_interface_enable(oi);
-
- /* If the router is ABR, originate summary routes */
- if (ospf6_check_and_set_router_abr(ospf6)) {
- ospf6_abr_enable_area(oa);
- ospf6_schedule_abr_task(oa->ospf6);
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN_HIDDEN (no_ospf6_interface_area,
- no_ospf6_interface_area_cmd,
- "no interface IFNAME area <A.B.C.D|(0-4294967295)>",
- NO_STR
- "Disable routing on an IPv6 interface\n"
- IFNAME_STR
- "Specify the OSPF6 area ID\n"
- "OSPF6 area ID in IPv4 address notation\n"
- "OSPF6 area ID in decimal notation\n"
- )
-{
- VTY_DECLVAR_CONTEXT(ospf6, ospf6);
- int idx_ifname = 2;
- int idx_ipv4 = 4;
- struct ospf6_interface *oi;
- struct ospf6_area *oa;
- struct interface *ifp;
- uint32_t area_id;
-
- vty_out(vty,
- "This command is deprecated, because it is not VRF-aware.\n");
- vty_out(vty,
- "Please, use \"no ipv6 ospf6 area\" on an interface instead.\n");
-
- /* find/create ospf6 interface */
- ifp = if_get_by_name(argv[idx_ifname]->arg, ospf6->vrf_id, ospf6->name);
-
- if (ifp == NULL) {
- vty_out(vty, "No such interface %s\n", argv[idx_ifname]->arg);
- return CMD_SUCCESS;
- }
-
- oi = (struct ospf6_interface *)ifp->info;
- if (oi == NULL) {
- vty_out(vty, "Interface %s not enabled\n", ifp->name);
- return CMD_SUCCESS;
- }
-
- /* parse Area-ID */
- if (inet_pton(AF_INET, argv[idx_ipv4]->arg, &area_id) != 1)
- area_id = htonl(strtoul(argv[idx_ipv4]->arg, NULL, 10));
-
- /* Verify Area */
- if (oi->area == NULL) {
- vty_out(vty, "%s not attached to area %s\n",
- oi->interface->name, argv[idx_ipv4]->arg);
- return CMD_SUCCESS;
- }
-
- if (oi->area->area_id != area_id) {
- vty_out(vty, "Wrong Area-ID: %s is attached to area %s\n",
- oi->interface->name, oi->area->name);
- return CMD_SUCCESS;
- }
-
- ospf6_interface_disable(oi);
-
- oa = oi->area;
- listnode_delete(oi->area->if_list, oi);
- oi->area = (struct ospf6_area *)NULL;
-
- /* Withdraw inter-area routes from this area, if necessary */
- if (oa->if_list->count == 0) {
- UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
- ospf6_abr_disable_area(oa);
- }
-
- oi->area_id = 0;
- oi->area_id_format = OSPF6_AREA_FMT_UNSET;
-
- return CMD_SUCCESS;
-}
-
DEFUN (ospf6_stub_router_admin,
ospf6_stub_router_admin_cmd,
"stub-router administrative",
@@ -2346,8 +2208,6 @@ void ospf6_top_init(void)
install_element(OSPF6_NODE, &ospf6_timers_lsa_cmd);
install_element(OSPF6_NODE, &no_ospf6_timers_lsa_cmd);
- install_element(OSPF6_NODE, &ospf6_interface_area_cmd);
- install_element(OSPF6_NODE, &no_ospf6_interface_area_cmd);
install_element(OSPF6_NODE, &ospf6_stub_router_admin_cmd);
install_element(OSPF6_NODE, &no_ospf6_stub_router_admin_cmd);
diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h
index a38dad8..8288413 100644
--- a/ospf6d/ospf6_top.h
+++ b/ospf6d/ospf6_top.h
@@ -236,6 +236,8 @@ extern struct ospf6_master *om6;
/* prototypes */
extern void ospf6_master_init(struct event_loop *master);
+extern void ospf6_master_delete(void);
+
extern void install_element_ospf6_clear_process(void);
extern void ospf6_top_init(void);
extern void ospf6_delete(struct ospf6 *o);
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index 8bd0d8f..3245578 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -147,30 +147,22 @@ void ospf6_zebra_import_default_route(struct ospf6 *ospf6, bool unreg)
__func__);
}
-static int ospf6_zebra_import_check_update(ZAPI_CALLBACK_ARGS)
+static void ospf6_zebra_import_check_update(struct vrf *vrf,
+ struct prefix *matched,
+ struct zapi_route *nhr)
{
struct ospf6 *ospf6;
- struct zapi_route nhr;
- struct prefix matched;
- ospf6 = ospf6_lookup_by_vrf_id(vrf_id);
+ ospf6 = (struct ospf6 *)vrf->info;
if (ospf6 == NULL || !IS_OSPF6_ASBR(ospf6))
- return 0;
-
- if (!zapi_nexthop_update_decode(zclient->ibuf, &matched, &nhr)) {
- zlog_err("%s[%u]: Failure to decode route", __func__,
- ospf6->vrf_id);
- return -1;
- }
+ return;
- if (matched.family != AF_INET6 || matched.prefixlen != 0 ||
- nhr.type == ZEBRA_ROUTE_OSPF6)
- return 0;
+ if (matched->family != AF_INET6 || matched->prefixlen != 0 ||
+ nhr->type == ZEBRA_ROUTE_OSPF6)
+ return;
- ospf6->nssa_default_import_check.status = !!nhr.nexthop_num;
+ ospf6->nssa_default_import_check.status = !!nhr->nexthop_num;
ospf6_abr_nssa_type_7_defaults(ospf6);
-
- return 0;
}
static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS)
@@ -763,7 +755,6 @@ static zclient_handler *const ospf6_handlers[] = {
[ZEBRA_INTERFACE_ADDRESS_DELETE] = ospf6_zebra_if_address_update_delete,
[ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ospf6_zebra_read_route,
[ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ospf6_zebra_read_route,
- [ZEBRA_NEXTHOP_UPDATE] = ospf6_zebra_import_check_update,
};
void ospf6_zebra_init(struct event_loop *master)
@@ -773,6 +764,7 @@ void ospf6_zebra_init(struct event_loop *master)
array_size(ospf6_handlers));
zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs);
zclient->zebra_connected = ospf6_zebra_connected;
+ zclient->nexthop_update = ospf6_zebra_import_check_update;
/* Install command element for zebra node. */
install_element(VIEW_NODE, &show_ospf6_zebra_cmd);
diff --git a/ospf6d/subdir.am b/ospf6d/subdir.am
index f6d27c8..5f89af9 100644
--- a/ospf6d/subdir.am
+++ b/ospf6d/subdir.am
@@ -83,8 +83,10 @@ clippy_scan += \
ospf6d/ospf6_lsa.c \
ospf6d/ospf6_gr_helper.c \
ospf6d/ospf6_gr.c \
+ ospf6d/ospf6_interface.c \
ospf6d/ospf6_nssa.c \
ospf6d/ospf6_route.c \
+ ospf6d/ospf6_neighbor.c \
# end
nodist_ospf6d_ospf6d_SOURCES = \