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)
{
}
if (oi->state == OSPF6_INTERFACE_LOOPBACK
+ || oi->state == OSPF6_INTERFACE_POINTTOMULTIPOINT
|| oi->state == OSPF6_INTERFACE_POINTTOPOINT) {
struct ospf6_route *la_route;
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
}
- if (next_state == OSPF6_INTERFACE_POINTTOPOINT)
+ 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);
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 {
return "BROADCAST";
case OSPF_IFTYPE_POINTOPOINT:
return "POINTOPOINT";
+ case OSPF_IFTYPE_POINTOMULTIPOINT:
+ return "POINTOMULTIPOINT";
}
return "UNKNOWN";
}
DEFUN (ipv6_ospf6_network,
ipv6_ospf6_network_cmd,
- "ipv6 ospf6 network <broadcast|point-to-point>",
+ "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);
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 */
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");
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[];
}
/* 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;
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",
hello = (struct ospf6_hello *)((caddr_t)oh
+ sizeof(struct ospf6_header));
- if (oi->state == OSPF6_INTERFACE_POINTTOPOINT
+ 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
/* Set packet length. */
op->length = length;
- if (!addr && oi->state == OSPF6_INTERFACE_POINTTOPOINT
- && oi->p2xp_no_multicast_hello) {
+ 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;
memcpy(&on->linklocal_addr, addr, sizeof(struct in6_addr));
- if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT) {
+ 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 int need_adjacency(struct ospf6_neighbor *on)
{
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;
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_POINTTOPOINT)
+ || (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
struct ospf6_if_p2xp_neighcfg *p2xp_cfg = EVENT_ARG(event);
struct ospf6_interface *oi = p2xp_cfg->ospf6_if;
- if (oi->state != OSPF6_INTERFACE_POINTTOPOINT)
+ if (oi->state != OSPF6_INTERFACE_POINTTOPOINT
+ && oi->state != OSPF6_INTERFACE_POINTTOMULTIPOINT)
return;
p2xp_unicast_hello_sched(p2xp_cfg);
/* 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");
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:
/* 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))