ospf6d: add p2p interface support

Signed-off-by: Dinesh G Dutt <ddutt at cumulusnetworks.com>
Signed-off-by: Ayan Banerjee <ayabaner at gmail.com>
Reviewed-by: Scott Feldman <sfeldma at cumulusnetworks.com>
Reviewed-by: James Li <jli at cumulusnetworks.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
Dinesh Dutt 2013-08-24 07:55:00 +00:00 committed by David Lamparter
parent bf986da797
commit c5926a9223
8 changed files with 270 additions and 100 deletions

View File

@ -98,6 +98,10 @@ Sets interface's Router Priority. Default value is 1.
Sets interface's Inf-Trans-Delay. Default value is 1.
@end deffn
@deffn {Interface Command} {ipv6 ospf6 network (broadcast|point-to-point)} {}
Set explicitly network type for specifed interface.
@end deffn
@node Redistribute routes to OSPF6
@section Redistribute routes to OSPF6

View File

@ -50,6 +50,16 @@
#define OSPF_INITIAL_SEQUENCE_NUMBER 0x80000001
#define OSPF_MAX_SEQUENCE_NUMBER 0x7fffffff
/* OSPF Interface Types */
#define OSPF_IFTYPE_NONE 0
#define OSPF_IFTYPE_POINTOPOINT 1
#define OSPF_IFTYPE_BROADCAST 2
#define OSPF_IFTYPE_NBMA 3
#define OSPF_IFTYPE_POINTOMULTIPOINT 4
#define OSPF_IFTYPE_VIRTUALLINK 5
#define OSPF_IFTYPE_LOOPBACK 6
#define OSPF_IFTYPE_MAX 7
/* OSPF interface default values. */
#define OSPF_OUTPUT_COST_DEFAULT 10
#define OSPF_OUTPUT_COST_INFINITE UINT16_MAX

View File

@ -366,7 +366,8 @@ ospf6_flood_interface (struct ospf6_neighbor *from,
/* (5) flood the LSA out the interface. */
if (is_debug)
zlog_debug ("Schedule flooding for the interface");
if (if_is_broadcast (oi->interface))
if ((oi->type == OSPF_IFTYPE_BROADCAST) ||
(oi->type == OSPF_IFTYPE_POINTOPOINT))
{
ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
if (oi->thread_send_lsupdate == NULL)

View File

@ -94,6 +94,17 @@ ospf6_interface_lsdb_hook (struct ospf6_lsa *lsa)
}
}
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)
@ -122,6 +133,7 @@ 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;
@ -407,6 +419,7 @@ ospf6_interface_state_change (u_char next_state, struct ospf6_interface *oi)
(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 ||
@ -640,8 +653,10 @@ interface_up (struct thread *thread)
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
@ -1522,6 +1537,86 @@ 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 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)
{
@ -1581,6 +1676,11 @@ 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;
@ -1638,6 +1738,9 @@ ospf6_interface_init (void)
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,

View File

@ -56,6 +56,9 @@ struct ospf6_interface
/* I/F transmission delay */
u_int32_t transdelay;
/* Network Type */
u_char type;
/* Router Priority */
u_char priority;

View File

@ -215,7 +215,7 @@ ospf6_router_lsa_originate (struct thread *thread)
}
/* Point-to-Point interfaces */
if (if_is_pointopoint (oi->interface))
if (oi->type == OSPF_IFTYPE_POINTOPOINT)
{
for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
{
@ -233,7 +233,7 @@ ospf6_router_lsa_originate (struct thread *thread)
}
/* Broadcast and NBMA interfaces */
if (if_is_broadcast (oi->interface))
else if (oi->type == OSPF_IFTYPE_BROADCAST)
{
/* If this router is not DR,
and If this router not fully adjacent with DR,
@ -261,6 +261,10 @@ ospf6_router_lsa_originate (struct thread *thread)
lsdesc++;
}
else
{
assert (0); /* Unknown interface type */
}
/* Virtual links */
/* xxx */

View File

@ -1785,6 +1785,7 @@ ospf6_dbdesc_send (struct thread *thread)
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;
@ -1848,8 +1849,14 @@ ospf6_dbdesc_send (struct thread *thread)
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;
}
@ -1952,8 +1959,13 @@ ospf6_lsreq_send (struct thread *thread)
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;
}
@ -1964,7 +1976,7 @@ ospf6_lsupdate_send_neighbor (struct thread *thread)
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);
@ -1981,22 +1993,13 @@ ospf6_lsupdate_send_neighbor (struct thread *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 */
@ -2005,58 +2008,85 @@ ospf6_lsupdate_send_neighbor (struct thread *thread)
{
/* 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;
}
@ -2067,7 +2097,7 @@ ospf6_lsupdate_send_interface (struct thread *thread)
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);
@ -2088,41 +2118,46 @@ ospf6_lsupdate_send_interface (struct thread *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)
{
@ -2140,6 +2175,7 @@ ospf6_lsack_send_neighbor (struct thread *thread)
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;
@ -2166,16 +2202,16 @@ ospf6_lsack_send_neighbor (struct thread *thread)
{
/* 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));
@ -2183,13 +2219,24 @@ ospf6_lsack_send_neighbor (struct thread *thread)
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;
}
@ -2200,6 +2247,7 @@ ospf6_lsack_send_interface (struct thread *thread)
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;
@ -2226,16 +2274,16 @@ ospf6_lsack_send_interface (struct thread *thread)
{
/* 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));
@ -2243,16 +2291,21 @@ ospf6_lsack_send_interface (struct thread *thread)
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)
{

View File

@ -140,14 +140,6 @@ struct ospf_interface
/* OSPF Network Type. */
u_char type;
#define OSPF_IFTYPE_NONE 0
#define OSPF_IFTYPE_POINTOPOINT 1
#define OSPF_IFTYPE_BROADCAST 2
#define OSPF_IFTYPE_NBMA 3
#define OSPF_IFTYPE_POINTOMULTIPOINT 4
#define OSPF_IFTYPE_VIRTUALLINK 5
#define OSPF_IFTYPE_LOOPBACK 6
#define OSPF_IFTYPE_MAX 7
/* State of Interface State Machine. */
u_char state;