summaryrefslogtreecommitdiff
path: root/ospfd/ospf_packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospfd/ospf_packet.c')
-rw-r--r--ospfd/ospf_packet.c198
1 files changed, 116 insertions, 82 deletions
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 4c2f5d72b3..552acfd6d3 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -7,7 +7,7 @@
#include <zebra.h>
#include "monotime.h"
-#include "thread.h"
+#include "frrevent.h"
#include "memory.h"
#include "linklist.h"
#include "prefix.h"
@@ -28,6 +28,7 @@
#include "ospfd/ospf_network.h"
#include "ospfd/ospf_interface.h"
#include "ospfd/ospf_ism.h"
+#include "ospfd/ospf_abr.h"
#include "ospfd/ospf_asbr.h"
#include "ospfd/ospf_lsa.h"
#include "ospfd/ospf_lsdb.h"
@@ -307,8 +308,10 @@ static int ospf_check_md5_digest(struct ospf_interface *oi,
ck = ospf_crypt_key_lookup(OSPF_IF_PARAM(oi, auth_crypt),
ospfh->u.crypt.key_id);
if (ck == NULL) {
- flog_warn(EC_OSPF_MD5, "interface %s: ospf_check_md5 no key %d",
- IF_NAME(oi), ospfh->u.crypt.key_id);
+ flog_warn(
+ EC_OSPF_MD5,
+ "interface %s: ospf_check_md5 no key %d, Router-ID: %pI4",
+ IF_NAME(oi), ospfh->u.crypt.key_id, &ospfh->router_id);
return 0;
}
@@ -319,9 +322,9 @@ static int ospf_check_md5_digest(struct ospf_interface *oi,
&& ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum)) {
flog_warn(
EC_OSPF_MD5,
- "interface %s: ospf_check_md5 bad sequence %d (expect %d)",
+ "interface %s: ospf_check_md5 bad sequence %d (expect %d), Router-ID: %pI4",
IF_NAME(oi), ntohl(ospfh->u.crypt.crypt_seqnum),
- ntohl(nbr->crypt_seqnum));
+ ntohl(nbr->crypt_seqnum), &ospfh->router_id);
return 0;
}
@@ -344,9 +347,10 @@ static int ospf_check_md5_digest(struct ospf_interface *oi,
/* compare the two */
if (memcmp((caddr_t)ospfh + length, digest, OSPF_AUTH_MD5_SIZE)) {
- flog_warn(EC_OSPF_MD5,
- "interface %s: ospf_check_md5 checksum mismatch",
- IF_NAME(oi));
+ flog_warn(
+ EC_OSPF_MD5,
+ "interface %s: ospf_check_md5 checksum mismatch, Router-ID: %pI4",
+ IF_NAME(oi), &ospfh->router_id);
return 0;
}
@@ -425,20 +429,21 @@ static int ospf_make_md5_digest(struct ospf_interface *oi,
if (stream_get_endp(op->s) != op->length)
/* XXX size_t */
- flog_warn(EC_OSPF_MD5,
- "%s: length mismatch stream %lu ospf_packet %u",
- __func__, (unsigned long)stream_get_endp(op->s),
- op->length);
+ flog_warn(
+ EC_OSPF_MD5,
+ "%s: length mismatch stream %lu ospf_packet %u, Router-ID %pI4",
+ __func__, (unsigned long)stream_get_endp(op->s),
+ op->length, &ospfh->router_id);
return OSPF_AUTH_MD5_SIZE;
}
-static void ospf_ls_req_timer(struct thread *thread)
+static void ospf_ls_req_timer(struct event *thread)
{
struct ospf_neighbor *nbr;
- nbr = THREAD_ARG(thread);
+ nbr = EVENT_ARG(thread);
nbr->t_ls_req = NULL;
/* Send Link State Request. */
@@ -451,17 +456,17 @@ static void ospf_ls_req_timer(struct thread *thread)
void ospf_ls_req_event(struct ospf_neighbor *nbr)
{
- THREAD_OFF(nbr->t_ls_req);
- thread_add_event(master, ospf_ls_req_timer, nbr, 0, &nbr->t_ls_req);
+ EVENT_OFF(nbr->t_ls_req);
+ event_add_event(master, ospf_ls_req_timer, nbr, 0, &nbr->t_ls_req);
}
/* Cyclic timer function. Fist registered in ospf_nbr_new () in
ospf_neighbor.c */
-void ospf_ls_upd_timer(struct thread *thread)
+void ospf_ls_upd_timer(struct event *thread)
{
struct ospf_neighbor *nbr;
- nbr = THREAD_ARG(thread);
+ nbr = EVENT_ARG(thread);
nbr->t_ls_upd = NULL;
/* Send Link State Update. */
@@ -515,11 +520,11 @@ void ospf_ls_upd_timer(struct thread *thread)
OSPF_NSM_TIMER_ON(nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
}
-void ospf_ls_ack_timer(struct thread *thread)
+void ospf_ls_ack_timer(struct event *thread)
{
struct ospf_interface *oi;
- oi = THREAD_ARG(thread);
+ oi = EVENT_ARG(thread);
oi->t_ls_ack = NULL;
/* Send Link State Acknowledgment. */
@@ -603,9 +608,9 @@ static void ospf_write_frags(int fd, struct ospf_packet *op, struct ip *iph,
}
#endif /* WANT_OSPF_WRITE_FRAGMENT */
-static void ospf_write(struct thread *thread)
+static void ospf_write(struct event *thread)
{
- struct ospf *ospf = THREAD_ARG(thread);
+ struct ospf *ospf = EVENT_ARG(thread);
struct ospf_interface *oi;
struct ospf_packet *op;
struct sockaddr_in sa_dst;
@@ -613,7 +618,7 @@ static void ospf_write(struct thread *thread)
struct msghdr msg;
struct iovec iov[2];
uint8_t type;
- int ret;
+ int ret, fd;
int flags = 0;
struct listnode *node;
#ifdef WANT_OSPF_WRITE_FRAGMENT
@@ -628,11 +633,12 @@ static void ospf_write(struct thread *thread)
struct cmsghdr *cm = (struct cmsghdr *)cmsgbuf;
struct in_pktinfo *pi;
#endif
+ fd = ospf->fd;
- if (ospf->fd < 0 || ospf->oi_running == 0) {
+ if (fd < 0 || ospf->oi_running == 0) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s failed to send, fd %d, instance %u",
- __func__, ospf->fd, ospf->oi_running);
+ __func__, fd, ospf->oi_running);
return;
}
@@ -652,6 +658,15 @@ static void ospf_write(struct thread *thread)
/* convenience - max OSPF data per packet */
maxdatasize = oi->ifp->mtu - sizeof(struct ip);
#endif /* WANT_OSPF_WRITE_FRAGMENT */
+
+ /* Reset socket fd to use. */
+ fd = ospf->fd;
+
+ /* Check for per-interface socket */
+ if (ospf->intf_socket_enabled &&
+ (IF_OSPF_IF_INFO(oi->ifp))->oii_fd > 0)
+ fd = (IF_OSPF_IF_INFO(oi->ifp))->oii_fd;
+
/* Get one packet from queue. */
op = ospf_fifo_head(oi->obuf);
assert(op);
@@ -659,8 +674,7 @@ static void ospf_write(struct thread *thread)
if (op->dst.s_addr == htonl(OSPF_ALLSPFROUTERS)
|| op->dst.s_addr == htonl(OSPF_ALLDROUTERS))
- ospf_if_ipmulticast(ospf, oi->address,
- oi->ifp->ifindex);
+ ospf_if_ipmulticast(fd, oi->address, oi->ifp->ifindex);
/* Rewrite the md5 signature & update the seq */
ospf_make_md5_digest(oi, op);
@@ -755,13 +769,13 @@ static void ospf_write(struct thread *thread)
#ifdef WANT_OSPF_WRITE_FRAGMENT
if (op->length > maxdatasize)
- ospf_write_frags(ospf->fd, op, &iph, &msg, maxdatasize,
+ ospf_write_frags(fd, op, &iph, &msg, maxdatasize,
oi->ifp->mtu, flags, type);
#endif /* WANT_OSPF_WRITE_FRAGMENT */
/* send final fragment (could be first) */
sockopt_iphdrincl_swab_htosys(&iph);
- ret = sendmsg(ospf->fd, &msg, flags);
+ ret = sendmsg(fd, &msg, flags);
sockopt_iphdrincl_swab_systoh(&iph);
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
@@ -842,8 +856,8 @@ static void ospf_write(struct thread *thread)
/* If packets still remain in queue, call write thread. */
if (!list_isempty(ospf->oi_write_q))
- thread_add_write(master, ospf_write, ospf, ospf->fd,
- &ospf->t_write);
+ event_add_write(master, ospf_write, ospf, ospf->fd,
+ &ospf->t_write);
}
/* OSPF Hello message read -- RFC2328 Section 10.5. */
@@ -895,11 +909,11 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
/* Compare Router Dead Interval. */
if (OSPF_IF_PARAM(oi, v_wait) != ntohl(hello->dead_interval)) {
- flog_warn(EC_OSPF_PACKET,
- "Packet %pI4 [Hello:RECV]: RouterDeadInterval mismatch (expected %u, but received %u).",
- &ospfh->router_id,
- OSPF_IF_PARAM(oi, v_wait),
- ntohl(hello->dead_interval));
+ flog_warn(
+ EC_OSPF_PACKET,
+ "Packet %pI4 [Hello:RECV]: RouterDeadInterval mismatch on %s (expected %u, but received %u).",
+ &ospfh->router_id, IF_NAME(oi),
+ OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
return;
}
@@ -909,8 +923,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
!= ntohs(hello->hello_interval)) {
flog_warn(
EC_OSPF_PACKET,
- "Packet %pI4 [Hello:RECV]: HelloInterval mismatch (expected %u, but received %u).",
- &ospfh->router_id,
+ "Packet %pI4 [Hello:RECV]: HelloInterval mismatch on %s (expected %u, but received %u).",
+ &ospfh->router_id, IF_NAME(oi),
OSPF_IF_PARAM(oi, v_hello),
ntohs(hello->hello_interval));
return;
@@ -918,8 +932,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
}
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("Packet %pI4 [Hello:RECV]: Options %s vrf %s",
- &ospfh->router_id,
+ zlog_debug("Packet %pI4 [Hello:RECV]: Options on %s %s vrf %s",
+ &ospfh->router_id, IF_NAME(oi),
ospf_options_dump(hello->options),
ospf_vrf_id_to_name(oi->ospf->vrf_id));
@@ -933,8 +947,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
* relationship.
*/
flog_warn(EC_OSPF_PACKET,
- "Packet %pI4 [Hello:RECV]: T-bit on, drop it.",
- &ospfh->router_id);
+ "Packet %pI4 [Hello:RECV]: T-bit ON on %s, drop it.",
+ &ospfh->router_id, IF_NAME(oi));
return;
}
#endif /* REJECT_IF_TBIT_ON */
@@ -946,8 +960,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
* the bit should be set in DD packet only.
*/
flog_warn(EC_OSPF_PACKET,
- "Packet %pI4 [Hello:RECV]: O-bit abuse?",
- &ospfh->router_id);
+ "Packet %pI4 [Hello:RECV]: O-bit abuse? on %s",
+ &ospfh->router_id, IF_NAME(oi));
#ifdef STRICT_OBIT_USAGE_CHECK
return; /* Reject this packet. */
#else /* STRICT_OBIT_USAGE_CHECK */
@@ -2101,6 +2115,14 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
if (ospf_flood(oi->ospf, nbr, current, lsa)
< 0) /* Trap NSSA later. */
DISCARD_LSA(lsa, 5);
+
+ /* GR: check for network topology change. */
+ if (ospf->gr_info.restart_in_progress &&
+ ((lsa->data->type == OSPF_ROUTER_LSA ||
+ lsa->data->type == OSPF_NETWORK_LSA)))
+ ospf_gr_check_lsdb_consistency(oi->ospf,
+ oi->area);
+
continue;
}
@@ -2213,9 +2235,6 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
assert(listcount(lsas) == 0);
list_delete(&lsas);
-
- if (ospf->gr_info.restart_in_progress)
- ospf_gr_check_lsdb_consistency(oi->ospf, oi->area);
}
/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
@@ -2469,10 +2488,11 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh)
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
flog_warn(
EC_OSPF_PACKET,
- "interface %s: auth-type mismatch, local %s, rcvd Null",
+ "interface %s: auth-type mismatch, local %s, rcvd Null, Router-ID %pI4",
IF_NAME(oi),
lookup_msg(ospf_auth_type_str,
- iface_auth_type, NULL));
+ iface_auth_type, NULL),
+ &ospfh->router_id);
return 0;
}
if (!ospf_check_sum(ospfh)) {
@@ -2491,18 +2511,20 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh)
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
flog_warn(
EC_OSPF_PACKET,
- "interface %s: auth-type mismatch, local %s, rcvd Simple",
+ "interface %s: auth-type mismatch, local %s, rcvd Simple, Router-ID %pI4",
IF_NAME(oi),
lookup_msg(ospf_auth_type_str,
- iface_auth_type, NULL));
+ iface_auth_type, NULL),
+ &ospfh->router_id);
return 0;
}
if (memcmp(OSPF_IF_PARAM(oi, auth_simple), ospfh->u.auth_data,
OSPF_AUTH_SIMPLE_SIZE)) {
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
- flog_warn(EC_OSPF_PACKET,
- "interface %s: Simple auth failed",
- IF_NAME(oi));
+ flog_warn(
+ EC_OSPF_PACKET,
+ "interface %s: Simple auth failed, Router-ID %pI4",
+ IF_NAME(oi), &ospfh->router_id);
return 0;
}
if (!ospf_check_sum(ospfh)) {
@@ -2521,18 +2543,19 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh)
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
flog_warn(
EC_OSPF_PACKET,
- "interface %s: auth-type mismatch, local %s, rcvd Cryptographic",
+ "interface %s: auth-type mismatch, local %s, rcvd Cryptographic, Router-ID %pI4",
IF_NAME(oi),
lookup_msg(ospf_auth_type_str,
- iface_auth_type, NULL));
+ iface_auth_type, NULL),
+ &ospfh->router_id);
return 0;
}
if (ospfh->checksum) {
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
flog_warn(
EC_OSPF_PACKET,
- "interface %s: OSPF header checksum is not 0",
- IF_NAME(oi));
+ "interface %s: OSPF header checksum is not 0, Router-ID %pI4",
+ IF_NAME(oi), &ospfh->router_id);
return 0;
}
/* only MD5 crypto method can pass ospf_packet_examin() */
@@ -2545,9 +2568,10 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh)
bug? */
!ospf_check_md5_digest(oi, ospfh)) {
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
- flog_warn(EC_OSPF_MD5,
- "interface %s: MD5 auth failed",
- IF_NAME(oi));
+ flog_warn(
+ EC_OSPF_MD5,
+ "interface %s: MD5 auth failed, Router-ID %pI4",
+ IF_NAME(oi), &ospfh->router_id);
return 0;
}
return 1;
@@ -2555,8 +2579,8 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh)
if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
flog_warn(
EC_OSPF_PACKET,
- "interface %s: invalid packet auth-type (%02x)",
- IF_NAME(oi), pkt_auth_type);
+ "interface %s: invalid packet auth-type (%02x), Router-ID %pI4",
+ IF_NAME(oi), pkt_auth_type, &ospfh->router_id);
return 0;
}
}
@@ -3188,17 +3212,17 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf)
}
/* Starting point of packet process function. */
-void ospf_read(struct thread *thread)
+void ospf_read(struct event *thread)
{
struct ospf *ospf;
int32_t count = 0;
enum ospf_read_return_enum ret;
/* first of all get interface pointer. */
- ospf = THREAD_ARG(thread);
+ ospf = EVENT_ARG(thread);
/* prepare for next packet. */
- thread_add_read(master, ospf_read, ospf, ospf->fd, &ospf->t_read);
+ event_add_read(master, ospf_read, ospf, ospf->fd, &ospf->t_read);
while (count < ospf->write_oi_count) {
count++;
@@ -3317,6 +3341,14 @@ static int ospf_make_hello(struct ospf_interface *oi, struct stream *s)
else
stream_putw(s, 0); /* hello-interval of 0 for fast-hellos */
+ /* Check if flood-reduction is enabled,
+ * if yes set the DC bit in the options.
+ */
+ if (OSPF_FR_CONFIG(oi->ospf, oi->area))
+ SET_FLAG(OPTIONS(oi), OSPF_OPTION_DC);
+ else if (CHECK_FLAG(OPTIONS(oi), OSPF_OPTION_DC))
+ UNSET_FLAG(OPTIONS(oi), OSPF_OPTION_DC);
+
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("%s: options: %x, int: %s", __func__, OPTIONS(oi),
IF_NAME(oi));
@@ -3405,6 +3437,8 @@ static int ospf_make_db_desc(struct ospf_interface *oi,
options = OPTIONS(oi);
if (CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE))
SET_FLAG(options, OSPF_OPTION_O);
+ if (OSPF_FR_CONFIG(oi->ospf, oi->area))
+ SET_FLAG(options, OSPF_OPTION_DC);
stream_putc(s, options);
/* DD flags */
@@ -3713,11 +3747,11 @@ static void ospf_poll_send(struct ospf_nbr_nbma *nbr_nbma)
ospf_hello_send_sub(oi, nbr_nbma->addr.s_addr);
}
-void ospf_poll_timer(struct thread *thread)
+void ospf_poll_timer(struct event *thread)
{
struct ospf_nbr_nbma *nbr_nbma;
- nbr_nbma = THREAD_ARG(thread);
+ nbr_nbma = EVENT_ARG(thread);
nbr_nbma->t_poll = NULL;
if (IS_DEBUG_OSPF(nsm, NSM_TIMERS))
@@ -3732,11 +3766,11 @@ void ospf_poll_timer(struct thread *thread)
}
-void ospf_hello_reply_timer(struct thread *thread)
+void ospf_hello_reply_timer(struct event *thread)
{
struct ospf_neighbor *nbr;
- nbr = THREAD_ARG(thread);
+ nbr = EVENT_ARG(thread);
nbr->t_hello_reply = NULL;
if (IS_DEBUG_OSPF(nsm, NSM_TIMERS))
@@ -4047,7 +4081,7 @@ static void ospf_ls_upd_queue_send(struct ospf_interface *oi,
ospf_packet_add(oi, op);
/* Call ospf_write() right away to send ospf packets to neighbors */
if (send_lsupd_now) {
- struct thread os_packet_thd;
+ struct event os_packet_thd;
os_packet_thd.arg = (void *)oi->ospf;
if (oi->on_write_q == 0) {
@@ -4071,16 +4105,16 @@ static void ospf_ls_upd_queue_send(struct ospf_interface *oi,
* is actually turned off.
*/
if (list_isempty(oi->ospf->oi_write_q))
- THREAD_OFF(oi->ospf->t_write);
+ EVENT_OFF(oi->ospf->t_write);
} else {
/* Hook thread to write packet. */
OSPF_ISM_WRITE_ON(oi->ospf);
}
}
-static void ospf_ls_upd_send_queue_event(struct thread *thread)
+static void ospf_ls_upd_send_queue_event(struct event *thread)
{
- struct ospf_interface *oi = THREAD_ARG(thread);
+ struct ospf_interface *oi = EVENT_ARG(thread);
struct route_node *rn;
struct route_node *rnext;
struct list *update;
@@ -4115,8 +4149,8 @@ static void ospf_ls_upd_send_queue_event(struct thread *thread)
"%s: update lists not cleared, %d nodes to try again, raising new event",
__func__, again);
oi->t_ls_upd_event = NULL;
- thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
- &oi->t_ls_upd_event);
+ event_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
+ &oi->t_ls_upd_event);
}
if (IS_DEBUG_OSPF_EVENT)
@@ -4187,8 +4221,8 @@ void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag,
rn->p.u.prefix4, 1);
}
} else
- thread_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
- &oi->t_ls_upd_event);
+ event_add_event(master, ospf_ls_upd_send_queue_event, oi, 0,
+ &oi->t_ls_upd_event);
}
static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack,
@@ -4225,9 +4259,9 @@ static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack,
OSPF_ISM_WRITE_ON(oi->ospf);
}
-static void ospf_ls_ack_send_event(struct thread *thread)
+static void ospf_ls_ack_send_event(struct event *thread)
{
- struct ospf_interface *oi = THREAD_ARG(thread);
+ struct ospf_interface *oi = EVENT_ARG(thread);
oi->t_ls_ack_direct = NULL;
@@ -4251,8 +4285,8 @@ void ospf_ls_ack_send(struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
listnode_add(oi->ls_ack_direct.ls_ack, ospf_lsa_lock(lsa));
- thread_add_event(master, ospf_ls_ack_send_event, oi, 0,
- &oi->t_ls_ack_direct);
+ event_add_event(master, ospf_ls_ack_send_event, oi, 0,
+ &oi->t_ls_ack_direct);
}
/* Send Link State Acknowledgment delayed. */