mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 21:50:39 +00:00
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:
parent
bf986da797
commit
c5926a9223
@ -98,6 +98,10 @@ Sets interface's Router Priority. Default value is 1.
|
|||||||
Sets interface's Inf-Trans-Delay. Default value is 1.
|
Sets interface's Inf-Trans-Delay. Default value is 1.
|
||||||
@end deffn
|
@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
|
@node Redistribute routes to OSPF6
|
||||||
@section Redistribute routes to OSPF6
|
@section Redistribute routes to OSPF6
|
||||||
|
|
||||||
|
@ -50,6 +50,16 @@
|
|||||||
#define OSPF_INITIAL_SEQUENCE_NUMBER 0x80000001
|
#define OSPF_INITIAL_SEQUENCE_NUMBER 0x80000001
|
||||||
#define OSPF_MAX_SEQUENCE_NUMBER 0x7fffffff
|
#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. */
|
/* OSPF interface default values. */
|
||||||
#define OSPF_OUTPUT_COST_DEFAULT 10
|
#define OSPF_OUTPUT_COST_DEFAULT 10
|
||||||
#define OSPF_OUTPUT_COST_INFINITE UINT16_MAX
|
#define OSPF_OUTPUT_COST_INFINITE UINT16_MAX
|
||||||
|
@ -366,7 +366,8 @@ ospf6_flood_interface (struct ospf6_neighbor *from,
|
|||||||
/* (5) flood the LSA out the interface. */
|
/* (5) flood the LSA out the interface. */
|
||||||
if (is_debug)
|
if (is_debug)
|
||||||
zlog_debug ("Schedule flooding for the interface");
|
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);
|
ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
|
||||||
if (oi->thread_send_lsupdate == NULL)
|
if (oi->thread_send_lsupdate == NULL)
|
||||||
|
@ -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 */
|
/* Create new ospf6 interface structure */
|
||||||
struct ospf6_interface *
|
struct ospf6_interface *
|
||||||
ospf6_interface_create (struct interface *ifp)
|
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->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
|
||||||
oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
|
oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
|
||||||
oi->cost = OSPF6_INTERFACE_COST;
|
oi->cost = OSPF6_INTERFACE_COST;
|
||||||
|
oi->type = ospf6_default_iftype (ifp);
|
||||||
oi->state = OSPF6_INTERFACE_DOWN;
|
oi->state = OSPF6_INTERFACE_DOWN;
|
||||||
oi->flag = 0;
|
oi->flag = 0;
|
||||||
oi->mtu_ignore = 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_DR &&
|
||||||
next_state != OSPF6_INTERFACE_BDR))
|
next_state != OSPF6_INTERFACE_BDR))
|
||||||
ospf6_sso (oi->interface->ifindex, &alldrouters6, IPV6_LEAVE_GROUP);
|
ospf6_sso (oi->interface->ifindex, &alldrouters6, IPV6_LEAVE_GROUP);
|
||||||
|
|
||||||
if ((prev_state != OSPF6_INTERFACE_DR &&
|
if ((prev_state != OSPF6_INTERFACE_DR &&
|
||||||
prev_state != OSPF6_INTERFACE_BDR) &&
|
prev_state != OSPF6_INTERFACE_BDR) &&
|
||||||
(next_state == OSPF6_INTERFACE_DR ||
|
(next_state == OSPF6_INTERFACE_DR ||
|
||||||
@ -640,8 +653,10 @@ interface_up (struct thread *thread)
|
|||||||
thread_add_event (master, ospf6_hello_send, oi, 0);
|
thread_add_event (master, ospf6_hello_send, oi, 0);
|
||||||
|
|
||||||
/* decide next interface state */
|
/* 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);
|
ospf6_interface_state_change (OSPF6_INTERFACE_POINTTOPOINT, oi);
|
||||||
|
}
|
||||||
else if (oi->priority == 0)
|
else if (oi->priority == 0)
|
||||||
ospf6_interface_state_change (OSPF6_INTERFACE_DROTHER, oi);
|
ospf6_interface_state_change (OSPF6_INTERFACE_DROTHER, oi);
|
||||||
else
|
else
|
||||||
@ -1522,6 +1537,86 @@ DEFUN (no_ipv6_ospf6_advertise_prefix_list,
|
|||||||
return CMD_SUCCESS;
|
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
|
static int
|
||||||
config_write_ospf6_interface (struct vty *vty)
|
config_write_ospf6_interface (struct vty *vty)
|
||||||
{
|
{
|
||||||
@ -1581,6 +1676,11 @@ config_write_ospf6_interface (struct vty *vty)
|
|||||||
if (oi->mtu_ignore)
|
if (oi->mtu_ignore)
|
||||||
vty_out (vty, " ipv6 ospf6 mtu-ignore%s", VNL);
|
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);
|
vty_out (vty, "!%s", VNL);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -1638,6 +1738,9 @@ ospf6_interface_init (void)
|
|||||||
|
|
||||||
install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
|
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, &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,
|
DEFUN (debug_ospf6_interface,
|
||||||
|
@ -56,6 +56,9 @@ struct ospf6_interface
|
|||||||
/* I/F transmission delay */
|
/* I/F transmission delay */
|
||||||
u_int32_t transdelay;
|
u_int32_t transdelay;
|
||||||
|
|
||||||
|
/* Network Type */
|
||||||
|
u_char type;
|
||||||
|
|
||||||
/* Router Priority */
|
/* Router Priority */
|
||||||
u_char priority;
|
u_char priority;
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ ospf6_router_lsa_originate (struct thread *thread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Point-to-Point interfaces */
|
/* 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))
|
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 */
|
/* Broadcast and NBMA interfaces */
|
||||||
if (if_is_broadcast (oi->interface))
|
else if (oi->type == OSPF_IFTYPE_BROADCAST)
|
||||||
{
|
{
|
||||||
/* If this router is not DR,
|
/* If this router is not DR,
|
||||||
and If this router not fully adjacent with DR,
|
and If this router not fully adjacent with DR,
|
||||||
@ -261,6 +261,10 @@ ospf6_router_lsa_originate (struct thread *thread)
|
|||||||
|
|
||||||
lsdesc++;
|
lsdesc++;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert (0); /* Unknown interface type */
|
||||||
|
}
|
||||||
|
|
||||||
/* Virtual links */
|
/* Virtual links */
|
||||||
/* xxx */
|
/* xxx */
|
||||||
|
@ -1785,6 +1785,7 @@ ospf6_dbdesc_send (struct thread *thread)
|
|||||||
struct ospf6_dbdesc *dbdesc;
|
struct ospf6_dbdesc *dbdesc;
|
||||||
u_char *p;
|
u_char *p;
|
||||||
struct ospf6_lsa *lsa;
|
struct ospf6_lsa *lsa;
|
||||||
|
struct in6_addr *dst;
|
||||||
|
|
||||||
on = (struct ospf6_neighbor *) THREAD_ARG (thread);
|
on = (struct ospf6_neighbor *) THREAD_ARG (thread);
|
||||||
on->thread_send_dbdesc = (struct thread *) NULL;
|
on->thread_send_dbdesc = (struct thread *) NULL;
|
||||||
@ -1848,8 +1849,14 @@ ospf6_dbdesc_send (struct thread *thread)
|
|||||||
oh->type = OSPF6_MESSAGE_TYPE_DBDESC;
|
oh->type = OSPF6_MESSAGE_TYPE_DBDESC;
|
||||||
oh->length = htons (p - sendbuf);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1952,8 +1959,13 @@ ospf6_lsreq_send (struct thread *thread)
|
|||||||
oh->type = OSPF6_MESSAGE_TYPE_LSREQ;
|
oh->type = OSPF6_MESSAGE_TYPE_LSREQ;
|
||||||
oh->length = htons (p - sendbuf);
|
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);
|
on->ospf6_if, oh);
|
||||||
|
else
|
||||||
|
ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
|
||||||
|
on->ospf6_if, oh);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1964,7 +1976,7 @@ ospf6_lsupdate_send_neighbor (struct thread *thread)
|
|||||||
struct ospf6_header *oh;
|
struct ospf6_header *oh;
|
||||||
struct ospf6_lsupdate *lsupdate;
|
struct ospf6_lsupdate *lsupdate;
|
||||||
u_char *p;
|
u_char *p;
|
||||||
int num;
|
int lsa_cnt;
|
||||||
struct ospf6_lsa *lsa;
|
struct ospf6_lsa *lsa;
|
||||||
|
|
||||||
on = (struct ospf6_neighbor *) THREAD_ARG (thread);
|
on = (struct ospf6_neighbor *) THREAD_ARG (thread);
|
||||||
@ -1981,22 +1993,13 @@ ospf6_lsupdate_send_neighbor (struct thread *thread)
|
|||||||
return 0;
|
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);
|
memset (sendbuf, 0, iobuflen);
|
||||||
oh = (struct ospf6_header *) sendbuf;
|
oh = (struct ospf6_header *) sendbuf;
|
||||||
lsupdate = (struct ospf6_lsupdate *)
|
lsupdate = (struct ospf6_lsupdate *)
|
||||||
((caddr_t) oh + sizeof (struct ospf6_header));
|
((caddr_t) oh + sizeof (struct ospf6_header));
|
||||||
|
|
||||||
p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
|
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
|
/* lsupdate_list lists those LSA which doesn't need to be
|
||||||
retransmitted. remove those from the list */
|
retransmitted. remove those from the list */
|
||||||
@ -2005,58 +2008,85 @@ ospf6_lsupdate_send_neighbor (struct thread *thread)
|
|||||||
{
|
{
|
||||||
/* MTU check */
|
/* MTU check */
|
||||||
if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
|
if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
|
||||||
> ospf6_packet_max(on->ospf6_if))
|
> ospf6_packet_max(on->ospf6_if))
|
||||||
{
|
{
|
||||||
ospf6_lsa_unlock (lsa);
|
ospf6_lsa_unlock (lsa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
|
ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
|
||||||
memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
|
memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
|
||||||
p += OSPF6_LSA_SIZE (lsa->header);
|
p += OSPF6_LSA_SIZE (lsa->header);
|
||||||
num++;
|
lsa_cnt++;
|
||||||
|
|
||||||
assert (lsa->lock == 2);
|
assert (lsa->lock == 2);
|
||||||
ospf6_lsdb_remove (lsa, on->lsupdate_list);
|
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;
|
for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
|
||||||
lsa = ospf6_lsdb_next (lsa))
|
lsa = ospf6_lsdb_next (lsa))
|
||||||
{
|
{
|
||||||
/* MTU check */
|
/* MTU check */
|
||||||
if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
|
if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
|
||||||
> ospf6_packet_max(on->ospf6_if))
|
> ospf6_packet_max(on->ospf6_if))
|
||||||
{
|
{
|
||||||
ospf6_lsa_unlock (lsa);
|
ospf6_lsa_unlock (lsa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
|
ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
|
||||||
memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
|
memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
|
||||||
p += OSPF6_LSA_SIZE (lsa->header);
|
p += OSPF6_LSA_SIZE (lsa->header);
|
||||||
num++;
|
lsa_cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
lsupdate->lsa_number = htonl (num);
|
if (lsa_cnt)
|
||||||
|
|
||||||
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 (on->lsupdate_list->count != 0)
|
oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
|
||||||
on->thread_send_lsupdate =
|
oh->length = htons (p - sendbuf);
|
||||||
thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
|
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
|
else
|
||||||
on->thread_send_lsupdate =
|
ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
|
||||||
thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,
|
on->ospf6_if, oh);
|
||||||
on->ospf6_if->rxmt_interval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2067,7 +2097,7 @@ ospf6_lsupdate_send_interface (struct thread *thread)
|
|||||||
struct ospf6_header *oh;
|
struct ospf6_header *oh;
|
||||||
struct ospf6_lsupdate *lsupdate;
|
struct ospf6_lsupdate *lsupdate;
|
||||||
u_char *p;
|
u_char *p;
|
||||||
int num;
|
int lsa_cnt;
|
||||||
struct ospf6_lsa *lsa;
|
struct ospf6_lsa *lsa;
|
||||||
|
|
||||||
oi = (struct ospf6_interface *) THREAD_ARG (thread);
|
oi = (struct ospf6_interface *) THREAD_ARG (thread);
|
||||||
@ -2088,41 +2118,46 @@ ospf6_lsupdate_send_interface (struct thread *thread)
|
|||||||
memset (sendbuf, 0, iobuflen);
|
memset (sendbuf, 0, iobuflen);
|
||||||
oh = (struct ospf6_header *) sendbuf;
|
oh = (struct ospf6_header *) sendbuf;
|
||||||
lsupdate = (struct ospf6_lsupdate *)((caddr_t) oh +
|
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));
|
p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
|
||||||
num = 0;
|
lsa_cnt = 0;
|
||||||
|
|
||||||
for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
|
for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
|
||||||
lsa = ospf6_lsdb_next (lsa))
|
lsa = ospf6_lsdb_next (lsa))
|
||||||
{
|
{
|
||||||
/* MTU check */
|
/* MTU check */
|
||||||
if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header)))
|
if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header)))
|
||||||
> ospf6_packet_max(oi))
|
> ospf6_packet_max(oi))
|
||||||
{
|
{
|
||||||
ospf6_lsa_unlock (lsa);
|
ospf6_lsa_unlock (lsa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
|
ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
|
||||||
memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
|
memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
|
||||||
p += OSPF6_LSA_SIZE (lsa->header);
|
p += OSPF6_LSA_SIZE (lsa->header);
|
||||||
num++;
|
lsa_cnt++;
|
||||||
|
|
||||||
assert (lsa->lock == 2);
|
assert (lsa->lock == 2);
|
||||||
ospf6_lsdb_remove (lsa, oi->lsupdate_list);
|
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->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
|
||||||
oh->length = htons (p - sendbuf);
|
oh->length = htons (p - sendbuf);
|
||||||
|
|
||||||
if (oi->state == OSPF6_INTERFACE_DR ||
|
if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) ||
|
||||||
oi->state == OSPF6_INTERFACE_BDR)
|
(oi->state == OSPF6_INTERFACE_DR) ||
|
||||||
ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
|
(oi->state == OSPF6_INTERFACE_BDR))
|
||||||
else
|
ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
|
||||||
ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
|
else
|
||||||
|
ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (oi->lsupdate_list->count > 0)
|
if (oi->lsupdate_list->count > 0)
|
||||||
{
|
{
|
||||||
@ -2140,6 +2175,7 @@ ospf6_lsack_send_neighbor (struct thread *thread)
|
|||||||
struct ospf6_header *oh;
|
struct ospf6_header *oh;
|
||||||
u_char *p;
|
u_char *p;
|
||||||
struct ospf6_lsa *lsa;
|
struct ospf6_lsa *lsa;
|
||||||
|
int lsa_cnt = 0;
|
||||||
|
|
||||||
on = (struct ospf6_neighbor *) THREAD_ARG (thread);
|
on = (struct ospf6_neighbor *) THREAD_ARG (thread);
|
||||||
on->thread_send_lsack = (struct thread *) NULL;
|
on->thread_send_lsack = (struct thread *) NULL;
|
||||||
@ -2166,16 +2202,16 @@ ospf6_lsack_send_neighbor (struct thread *thread)
|
|||||||
{
|
{
|
||||||
/* MTU check */
|
/* MTU check */
|
||||||
if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if))
|
if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if))
|
||||||
{
|
{
|
||||||
/* if we run out of packet size/space here,
|
/* if we run out of packet size/space here,
|
||||||
better to try again soon. */
|
better to try again soon. */
|
||||||
THREAD_OFF (on->thread_send_lsack);
|
THREAD_OFF (on->thread_send_lsack);
|
||||||
on->thread_send_lsack =
|
on->thread_send_lsack =
|
||||||
thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
|
thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
|
||||||
|
|
||||||
ospf6_lsa_unlock (lsa);
|
ospf6_lsa_unlock (lsa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
|
ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
|
||||||
memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
|
memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
|
||||||
@ -2183,13 +2219,24 @@ ospf6_lsack_send_neighbor (struct thread *thread)
|
|||||||
|
|
||||||
assert (lsa->lock == 2);
|
assert (lsa->lock == 2);
|
||||||
ospf6_lsdb_remove (lsa, on->lsack_list);
|
ospf6_lsdb_remove (lsa, on->lsack_list);
|
||||||
|
lsa_cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
oh->type = OSPF6_MESSAGE_TYPE_LSACK;
|
if (lsa_cnt)
|
||||||
oh->length = htons (p - sendbuf);
|
{
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2200,6 +2247,7 @@ ospf6_lsack_send_interface (struct thread *thread)
|
|||||||
struct ospf6_header *oh;
|
struct ospf6_header *oh;
|
||||||
u_char *p;
|
u_char *p;
|
||||||
struct ospf6_lsa *lsa;
|
struct ospf6_lsa *lsa;
|
||||||
|
int lsa_cnt = 0;
|
||||||
|
|
||||||
oi = (struct ospf6_interface *) THREAD_ARG (thread);
|
oi = (struct ospf6_interface *) THREAD_ARG (thread);
|
||||||
oi->thread_send_lsack = (struct thread *) NULL;
|
oi->thread_send_lsack = (struct thread *) NULL;
|
||||||
@ -2226,16 +2274,16 @@ ospf6_lsack_send_interface (struct thread *thread)
|
|||||||
{
|
{
|
||||||
/* MTU check */
|
/* MTU check */
|
||||||
if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(oi))
|
if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(oi))
|
||||||
{
|
{
|
||||||
/* if we run out of packet size/space here,
|
/* if we run out of packet size/space here,
|
||||||
better to try again soon. */
|
better to try again soon. */
|
||||||
THREAD_OFF (oi->thread_send_lsack);
|
THREAD_OFF (oi->thread_send_lsack);
|
||||||
oi->thread_send_lsack =
|
oi->thread_send_lsack =
|
||||||
thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
|
thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
|
||||||
|
|
||||||
ospf6_lsa_unlock (lsa);
|
ospf6_lsa_unlock (lsa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
|
ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
|
||||||
memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
|
memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
|
||||||
@ -2243,16 +2291,21 @@ ospf6_lsack_send_interface (struct thread *thread)
|
|||||||
|
|
||||||
assert (lsa->lock == 2);
|
assert (lsa->lock == 2);
|
||||||
ospf6_lsdb_remove (lsa, oi->lsack_list);
|
ospf6_lsdb_remove (lsa, oi->lsack_list);
|
||||||
|
lsa_cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
oh->type = OSPF6_MESSAGE_TYPE_LSACK;
|
if (lsa_cnt)
|
||||||
oh->length = htons (p - sendbuf);
|
{
|
||||||
|
oh->type = OSPF6_MESSAGE_TYPE_LSACK;
|
||||||
|
oh->length = htons (p - sendbuf);
|
||||||
|
|
||||||
if (oi->state == OSPF6_INTERFACE_DR ||
|
if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) ||
|
||||||
oi->state == OSPF6_INTERFACE_BDR)
|
(oi->state == OSPF6_INTERFACE_DR) ||
|
||||||
ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
|
(oi->state == OSPF6_INTERFACE_BDR))
|
||||||
else
|
ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
|
||||||
ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
|
else
|
||||||
|
ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
|
||||||
|
}
|
||||||
|
|
||||||
if (oi->thread_send_lsack == NULL && oi->lsack_list->count > 0)
|
if (oi->thread_send_lsack == NULL && oi->lsack_list->count > 0)
|
||||||
{
|
{
|
||||||
|
@ -140,14 +140,6 @@ struct ospf_interface
|
|||||||
|
|
||||||
/* OSPF Network Type. */
|
/* OSPF Network Type. */
|
||||||
u_char 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. */
|
/* State of Interface State Machine. */
|
||||||
u_char state;
|
u_char state;
|
||||||
|
Loading…
Reference in New Issue
Block a user