}
}
+static u_char
+ospf6_default_iftype(struct interface *ifp)
+{
+ if (if_is_pointopoint (ifp))
+ return OSPF_IFTYPE_POINTOPOINT;
+ else if (if_is_loopback (ifp))
+ return OSPF_IFTYPE_LOOPBACK;
+ else
+ return OSPF_IFTYPE_BROADCAST;
+}
+
/* Create new ospf6 interface structure */
struct ospf6_interface *
ospf6_interface_create (struct interface *ifp)
oi->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
oi->cost = OSPF6_INTERFACE_COST;
+ oi->type = ospf6_default_iftype (ifp);
oi->state = OSPF6_INTERFACE_DOWN;
oi->flag = 0;
oi->mtu_ignore = 0;
(next_state != OSPF6_INTERFACE_DR &&
next_state != OSPF6_INTERFACE_BDR))
ospf6_sso (oi->interface->ifindex, &alldrouters6, IPV6_LEAVE_GROUP);
+
if ((prev_state != OSPF6_INTERFACE_DR &&
prev_state != OSPF6_INTERFACE_BDR) &&
(next_state == OSPF6_INTERFACE_DR ||
thread_add_event (master, ospf6_hello_send, oi, 0);
/* decide next interface state */
- if (if_is_pointopoint (oi->interface))
+ if ((if_is_pointopoint (oi->interface)) ||
+ (oi->type == OSPF_IFTYPE_POINTOPOINT)) {
ospf6_interface_state_change (OSPF6_INTERFACE_POINTTOPOINT, oi);
+ }
else if (oi->priority == 0)
ospf6_interface_state_change (OSPF6_INTERFACE_DROTHER, oi);
else
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 OSPFv6 broadcast network\n"
+ "Specify OSPF6 point-to-point network\n"
+ )
+{
+ struct ospf6_interface *oi;
+ struct interface *ifp;
+
+ ifp = (struct interface *) vty->index;
+ assert (ifp);
+
+ oi = (struct ospf6_interface *) ifp->info;
+ if (oi == NULL) {
+ oi = ospf6_interface_create (ifp);
+ }
+ assert (oi);
+
+ if (strncmp (argv[0], "b", 1) == 0)
+ {
+ if (oi->type == OSPF_IFTYPE_BROADCAST)
+ return CMD_SUCCESS;
+
+ oi->type = OSPF_IFTYPE_BROADCAST;
+ }
+ else if (strncmp (argv[0], "point-to-p", 10) == 0)
+ {
+ if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
+ return CMD_SUCCESS;
+ }
+ oi->type = OSPF_IFTYPE_POINTOPOINT;
+ }
+
+ /* Reset the interface */
+ thread_add_event (master, interface_down, oi, 0);
+ thread_add_event (master, interface_up, oi, 0);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ipv6_ospf6_network,
+ no_ipv6_ospf6_network_cmd,
+ "no ipv6 ospf6 network",
+ NO_STR
+ IP6_STR
+ OSPF6_STR
+ "Network Type\n"
+ "Default to whatever interface type system specifies"
+ )
+{
+ struct ospf6_interface *oi;
+ struct interface *ifp;
+ int type;
+
+ ifp = (struct interface *) vty->index;
+ assert (ifp);
+
+ oi = (struct ospf6_interface *) ifp->info;
+ if (oi == NULL) {
+ return CMD_SUCCESS;
+ }
+
+ type = ospf6_default_iftype (ifp);
+ if (oi->type == type)
+ {
+ return CMD_SUCCESS;
+ }
+ oi->type = type;
+
+ /* Reset the interface */
+ thread_add_event (master, interface_down, oi, 0);
+ thread_add_event (master, interface_up, oi, 0);
+
+ return CMD_SUCCESS;
+}
+
static int
config_write_ospf6_interface (struct vty *vty)
{
if (oi->mtu_ignore)
vty_out (vty, " ipv6 ospf6 mtu-ignore%s", VNL);
+ if (oi->type == OSPF_IFTYPE_POINTOPOINT)
+ vty_out (vty, " ipv6 ospf6 network point-to-point%s", VNL);
+ else if (oi->type == OSPF_IFTYPE_BROADCAST)
+ vty_out (vty, " ipv6 ospf6 network broadcast%s", VNL);
+
vty_out (vty, "!%s", VNL);
}
return 0;
install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_prefix_list_cmd);
+
+ install_element (INTERFACE_NODE, &ipv6_ospf6_network_cmd);
+ install_element (INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
}
DEFUN (debug_ospf6_interface,
struct ospf6_dbdesc *dbdesc;
u_char *p;
struct ospf6_lsa *lsa;
+ struct in6_addr *dst;
on = (struct ospf6_neighbor *) THREAD_ARG (thread);
on->thread_send_dbdesc = (struct thread *) NULL;
oh->type = OSPF6_MESSAGE_TYPE_DBDESC;
oh->length = htons (p - sendbuf);
- ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
- on->ospf6_if, oh);
+
+ if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
+ dst = &allspfrouters6;
+ else
+ dst = &on->linklocal_addr;
+
+ ospf6_send (on->ospf6_if->linklocal_addr, dst, on->ospf6_if, oh);
+
return 0;
}
oh->type = OSPF6_MESSAGE_TYPE_LSREQ;
oh->length = htons (p - sendbuf);
- ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
+ if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
+ ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6,
on->ospf6_if, oh);
+ else
+ ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
+ on->ospf6_if, oh);
+
return 0;
}
struct ospf6_header *oh;
struct ospf6_lsupdate *lsupdate;
u_char *p;
- int num;
+ int lsa_cnt;
struct ospf6_lsa *lsa;
on = (struct ospf6_neighbor *) THREAD_ARG (thread);
return 0;
}
- /* if we have nothing to send, return */
- if (on->lsupdate_list->count == 0 &&
- on->retrans_list->count == 0)
- {
- if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
- zlog_debug ("Quit to send (nothing to send)");
- return 0;
- }
-
memset (sendbuf, 0, iobuflen);
oh = (struct ospf6_header *) sendbuf;
lsupdate = (struct ospf6_lsupdate *)
((caddr_t) oh + sizeof (struct ospf6_header));
p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
- num = 0;
+ lsa_cnt = 0;
/* lsupdate_list lists those LSA which doesn't need to be
retransmitted. remove those from the list */
{
/* MTU check */
if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
- > ospf6_packet_max(on->ospf6_if))
- {
- ospf6_lsa_unlock (lsa);
- break;
- }
+ > ospf6_packet_max(on->ospf6_if))
+ {
+ ospf6_lsa_unlock (lsa);
+ break;
+ }
ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
p += OSPF6_LSA_SIZE (lsa->header);
- num++;
+ lsa_cnt++;
assert (lsa->lock == 2);
ospf6_lsdb_remove (lsa, on->lsupdate_list);
}
+ if (lsa_cnt)
+ {
+ oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
+ oh->length = htons (p - sendbuf);
+ lsupdate->lsa_number = htonl (lsa_cnt);
+
+ if ((on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) ||
+ (on->ospf6_if->state == OSPF6_INTERFACE_DR) ||
+ (on->ospf6_if->state == OSPF6_INTERFACE_BDR))
+ ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6,
+ on->ospf6_if, oh);
+ else
+ ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
+ on->ospf6_if, oh);
+ }
+
+ /* The addresses used for retransmissions are different from those sent the
+ first time and so we need to separate them here.
+ */
+ memset (sendbuf, 0, iobuflen);
+ oh = (struct ospf6_header *) sendbuf;
+ lsupdate = (struct ospf6_lsupdate *)
+ ((caddr_t) oh + sizeof (struct ospf6_header));
+ p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
+ lsa_cnt = 0;
+
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
lsa = ospf6_lsdb_next (lsa))
{
/* MTU check */
if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
- > ospf6_packet_max(on->ospf6_if))
- {
- ospf6_lsa_unlock (lsa);
- break;
- }
+ > ospf6_packet_max(on->ospf6_if))
+ {
+ ospf6_lsa_unlock (lsa);
+ break;
+ }
ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
p += OSPF6_LSA_SIZE (lsa->header);
- num++;
+ lsa_cnt++;
}
- lsupdate->lsa_number = htonl (num);
-
- oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
- oh->length = htons (p - sendbuf);
-
- ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
- on->ospf6_if, oh);
-
- if (on->lsupdate_list->count != 0 ||
- on->retrans_list->count != 0)
+ if (lsa_cnt)
{
- if (on->lsupdate_list->count != 0)
- on->thread_send_lsupdate =
- thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
+ oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
+ oh->length = htons (p - sendbuf);
+ lsupdate->lsa_number = htonl (lsa_cnt);
+
+ if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
+ ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6,
+ on->ospf6_if, oh);
else
- on->thread_send_lsupdate =
- thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,
- on->ospf6_if->rxmt_interval);
+ ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
+ on->ospf6_if, oh);
}
+ if (on->lsupdate_list->count != 0)
+ on->thread_send_lsupdate =
+ thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
+ else if (on->retrans_list->count != 0)
+ on->thread_send_lsupdate =
+ thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,
+ on->ospf6_if->rxmt_interval);
return 0;
}
struct ospf6_header *oh;
struct ospf6_lsupdate *lsupdate;
u_char *p;
- int num;
+ int lsa_cnt;
struct ospf6_lsa *lsa;
oi = (struct ospf6_interface *) THREAD_ARG (thread);
memset (sendbuf, 0, iobuflen);
oh = (struct ospf6_header *) sendbuf;
lsupdate = (struct ospf6_lsupdate *)((caddr_t) oh +
- sizeof (struct ospf6_header));
+ sizeof (struct ospf6_header));
p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
- num = 0;
+ lsa_cnt = 0;
for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
lsa = ospf6_lsdb_next (lsa))
{
/* MTU check */
if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header)))
- > ospf6_packet_max(oi))
- {
- ospf6_lsa_unlock (lsa);
- break;
- }
+ > ospf6_packet_max(oi))
+ {
+ ospf6_lsa_unlock (lsa);
+ break;
+ }
ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
p += OSPF6_LSA_SIZE (lsa->header);
- num++;
+ lsa_cnt++;
assert (lsa->lock == 2);
ospf6_lsdb_remove (lsa, oi->lsupdate_list);
}
- lsupdate->lsa_number = htonl (num);
+ if (lsa_cnt)
+ {
+ lsupdate->lsa_number = htonl (lsa_cnt);
- oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
- oh->length = htons (p - sendbuf);
+ oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
+ oh->length = htons (p - sendbuf);
- if (oi->state == OSPF6_INTERFACE_DR ||
- oi->state == OSPF6_INTERFACE_BDR)
- ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
- else
- ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
+ if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) ||
+ (oi->state == OSPF6_INTERFACE_DR) ||
+ (oi->state == OSPF6_INTERFACE_BDR))
+ ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
+ else
+ ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
+
+ }
if (oi->lsupdate_list->count > 0)
{
struct ospf6_header *oh;
u_char *p;
struct ospf6_lsa *lsa;
+ int lsa_cnt = 0;
on = (struct ospf6_neighbor *) THREAD_ARG (thread);
on->thread_send_lsack = (struct thread *) NULL;
{
/* MTU check */
if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if))
- {
- /* if we run out of packet size/space here,
- better to try again soon. */
- THREAD_OFF (on->thread_send_lsack);
- on->thread_send_lsack =
- thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
+ {
+ /* if we run out of packet size/space here,
+ better to try again soon. */
+ THREAD_OFF (on->thread_send_lsack);
+ on->thread_send_lsack =
+ thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
- ospf6_lsa_unlock (lsa);
- break;
- }
+ ospf6_lsa_unlock (lsa);
+ break;
+ }
ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
assert (lsa->lock == 2);
ospf6_lsdb_remove (lsa, on->lsack_list);
+ lsa_cnt++;
}
- oh->type = OSPF6_MESSAGE_TYPE_LSACK;
- oh->length = htons (p - sendbuf);
+ if (lsa_cnt)
+ {
+ oh->type = OSPF6_MESSAGE_TYPE_LSACK;
+ oh->length = htons (p - sendbuf);
+
+ ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
+ on->ospf6_if, oh);
+ }
+
+ if (on->thread_send_lsack == NULL && on->lsack_list->count > 0)
+ {
+ on->thread_send_lsack =
+ thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
+ }
- ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
- on->ospf6_if, oh);
return 0;
}
struct ospf6_header *oh;
u_char *p;
struct ospf6_lsa *lsa;
+ int lsa_cnt = 0;
oi = (struct ospf6_interface *) THREAD_ARG (thread);
oi->thread_send_lsack = (struct thread *) NULL;
{
/* MTU check */
if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(oi))
- {
- /* if we run out of packet size/space here,
- better to try again soon. */
- THREAD_OFF (oi->thread_send_lsack);
- oi->thread_send_lsack =
- thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
+ {
+ /* if we run out of packet size/space here,
+ better to try again soon. */
+ THREAD_OFF (oi->thread_send_lsack);
+ oi->thread_send_lsack =
+ thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
- ospf6_lsa_unlock (lsa);
- break;
- }
+ ospf6_lsa_unlock (lsa);
+ break;
+ }
ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
assert (lsa->lock == 2);
ospf6_lsdb_remove (lsa, oi->lsack_list);
+ lsa_cnt++;
}
- oh->type = OSPF6_MESSAGE_TYPE_LSACK;
- oh->length = htons (p - sendbuf);
+ if (lsa_cnt)
+ {
+ oh->type = OSPF6_MESSAGE_TYPE_LSACK;
+ oh->length = htons (p - sendbuf);
- if (oi->state == OSPF6_INTERFACE_DR ||
- oi->state == OSPF6_INTERFACE_BDR)
- ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
- else
- ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
+ if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) ||
+ (oi->state == OSPF6_INTERFACE_DR) ||
+ (oi->state == OSPF6_INTERFACE_BDR))
+ ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
+ else
+ ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
+ }
if (oi->thread_send_lsack == NULL && oi->lsack_list->count > 0)
{