diff options
Diffstat (limited to 'ospfd/ospf_packet.c')
| -rw-r--r-- | ospfd/ospf_packet.c | 198 |
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. */ |
