diff options
Diffstat (limited to 'ospfd')
| -rw-r--r-- | ospfd/.cvsignore | 14 | ||||
| -rw-r--r-- | ospfd/ospf_abr.c | 49 | ||||
| -rw-r--r-- | ospfd/ospf_asbr.c | 5 | ||||
| -rw-r--r-- | ospfd/ospf_ase.c | 1 | ||||
| -rw-r--r-- | ospfd/ospf_dump.c | 23 | ||||
| -rw-r--r-- | ospfd/ospf_dump.h | 3 | ||||
| -rw-r--r-- | ospfd/ospf_flood.c | 3 | ||||
| -rw-r--r-- | ospfd/ospf_lsa.c | 19 | ||||
| -rw-r--r-- | ospfd/ospf_lsa.h | 6 | ||||
| -rw-r--r-- | ospfd/ospf_main.c | 46 | ||||
| -rw-r--r-- | ospfd/ospf_network.c | 19 | ||||
| -rw-r--r-- | ospfd/ospf_packet.c | 593 | ||||
| -rw-r--r-- | ospfd/ospf_packet.h | 11 | ||||
| -rw-r--r-- | ospfd/ospf_route.c | 59 | ||||
| -rw-r--r-- | ospfd/ospf_spf.c | 19 | ||||
| -rw-r--r-- | ospfd/ospf_vty.c | 59 | ||||
| -rw-r--r-- | ospfd/ospf_zebra.c | 6 | ||||
| -rw-r--r-- | ospfd/ospf_zebra.h | 2 | ||||
| -rw-r--r-- | ospfd/ospfd.c | 2 | ||||
| -rw-r--r-- | ospfd/ospfd.h | 4 | 
20 files changed, 595 insertions, 348 deletions
| diff --git a/ospfd/.cvsignore b/ospfd/.cvsignore deleted file mode 100644 index 6fce629e..00000000 --- a/ospfd/.cvsignore +++ /dev/null @@ -1,14 +0,0 @@ -Makefile -Makefile.in -*.o -ospfd -ospfd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index 7a75194a..b7cc20dd 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -384,7 +384,7 @@ ospf_abr_nssa_am_elected (struct ospf_area *area)        if (best == NULL)        	best = &lsa->data->id;        else -        if ( IPV4_ADDR_CMP (&best, &lsa->data->id) < 0) +        if (IPV4_ADDR_CMP (&best->s_addr, &lsa->data->id.s_addr) < 0)            best = &lsa->data->id;      } @@ -395,7 +395,7 @@ ospf_abr_nssa_am_elected (struct ospf_area *area)      if (best == NULL)        return 1; -    if ( IPV4_ADDR_CMP (&best, &area->ospf->router_id) < 0) +    if (IPV4_ADDR_CMP (&best->s_addr, &area->ospf->router_id.s_addr) < 0)        return 1;      else        return 0; @@ -613,15 +613,6 @@ set_metric (struct ospf_lsa *lsa, u_int32_t metric)    memcpy(header->metric, mp, 3);  } -static int -ospf_abr_check_nssa_range (struct prefix_ipv4 *p, u_int32_t cost, -				   struct ospf_area *area) -{ -  /* The Type-7 is tested against the aggregated prefix and forwarded -       for lsa installation and flooding */ -  return 0; -} -  /* ospf_abr_translate_nssa */  static int  ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa) @@ -1577,42 +1568,6 @@ ospf_abr_send_nssa_aggregates (struct ospf *ospf) /* temporarily turned off */  }  static void -ospf_abr_announce_nssa_defaults (struct ospf *ospf) /* By ABR-Translator */ -{ -  struct listnode *node; -  struct ospf_area *area; - -  if (! IS_OSPF_ABR (ospf)) -    return; - -  if (IS_DEBUG_OSPF_NSSA) -    zlog_debug ("ospf_abr_announce_stub_defaults(): Start"); - -  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) -    { -      if (IS_DEBUG_OSPF_NSSA) -        zlog_debug ("ospf_abr_announce_nssa_defaults(): looking at area %s", -                   inet_ntoa (area->area_id)); - -      if (area->external_routing != OSPF_AREA_NSSA) -        continue; - -      if (OSPF_IS_AREA_BACKBONE (area)) -        continue; /* Sanity Check */ - -      /* if (!TranslatorRole continue V 1.0 look for "always" conf */ -      if (area->NSSATranslatorState) -        { -          if (IS_DEBUG_OSPF_NSSA) -            zlog_debug ("ospf_abr_announce_nssa_defaults(): " -                       "announcing 0.0.0.0/0 to this nssa"); -          /* ospf_abr_announce_nssa_asbr_to_as (&p, area->default_cost, area); */ -          /*ospf_abr_announce_network_to_area (&p, area->default_cost, area);*/ -        } -    } -} - -static void  ospf_abr_announce_stub_defaults (struct ospf *ospf)  {    struct listnode *node; diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c index c39efee1..a23b4f2b 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -284,6 +284,9 @@ ospf_redistribute_withdraw (struct ospf *ospf, u_char type)  	      continue;  	    ospf_external_lsa_flush (ospf, type, &ei->p,  				     ei->ifindex /*, ei->nexthop */); -	    ospf_external_info_delete (type, ei->p); + +	    ospf_external_info_free (ei); +	    route_unlock_node (rn); +	    rn->info = NULL;  	  }  } diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index 3c199311..6a72e31d 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -135,7 +135,6 @@ ospf_ase_complete_direct_routes (struct ospf_route *ro, struct in_addr nexthop)  {    struct listnode *node;    struct ospf_path *op; -  struct interface *ifp;    for (ALL_LIST_ELEMENTS_RO (ro->paths, node, op))      if (op->nexthop.s_addr == 0) diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index e65b2e33..7e11e251 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -115,6 +115,16 @@ const struct message ospf_network_type_msg[] =  };  const int ospf_network_type_msg_max = OSPF_IFTYPE_MAX; +/* AuType */ +const struct message ospf_auth_type_str[] = +{ +  { OSPF_AUTH_NULL,          "Null"          }, +  { OSPF_AUTH_SIMPLE,        "Simple"        }, +  { OSPF_AUTH_CRYPTOGRAPHIC, "Cryptographic" }, +}; +const size_t ospf_auth_type_str_max = sizeof (ospf_auth_type_str) / +  sizeof (ospf_auth_type_str[0]); +  /* Configuration debug option variables. */  unsigned long conf_debug_ospf_packet[5] = {0, 0, 0, 0, 0};  unsigned long conf_debug_ospf_event = 0; @@ -657,18 +667,19 @@ static void  ospf_header_dump (struct ospf_header *ospfh)  {    char buf[9]; +  u_int16_t auth_type = ntohs (ospfh->auth_type);    zlog_debug ("Header");    zlog_debug ("  Version %d", ospfh->version);    zlog_debug ("  Type %d (%s)", ospfh->type, -	     ospf_packet_type_str[ospfh->type]); +	     LOOKUP (ospf_packet_type_str, ospfh->type));    zlog_debug ("  Packet Len %d", ntohs (ospfh->length));    zlog_debug ("  Router ID %s", inet_ntoa (ospfh->router_id));    zlog_debug ("  Area ID %s", inet_ntoa (ospfh->area_id));    zlog_debug ("  Checksum 0x%x", ntohs (ospfh->checksum)); -  zlog_debug ("  AuType %d", ntohs (ospfh->auth_type)); +  zlog_debug ("  AuType %s", LOOKUP (ospf_auth_type_str, auth_type)); -  switch (ntohs (ospfh->auth_type)) +  switch (auth_type)      {      case OSPF_AUTH_NULL:        break; @@ -1457,7 +1468,7 @@ DEFUN (show_debugging_ospf,      if (IS_DEBUG_OSPF_PACKET (i, SEND) && IS_DEBUG_OSPF_PACKET (i, RECV))        {  	vty_out (vty, "  OSPF packet %s%s debugging is on%s", -		 ospf_packet_type_str[i + 1], +		 LOOKUP (ospf_packet_type_str, i + 1),  		 IS_DEBUG_OSPF_PACKET (i, DETAIL) ? " detail" : "",  		 VTY_NEWLINE);        } @@ -1465,12 +1476,12 @@ DEFUN (show_debugging_ospf,        {  	if (IS_DEBUG_OSPF_PACKET (i, SEND))  	  vty_out (vty, "  OSPF packet %s send%s debugging is on%s", -		   ospf_packet_type_str[i + 1], +		   LOOKUP (ospf_packet_type_str, i + 1),  		   IS_DEBUG_OSPF_PACKET (i, DETAIL) ? " detail" : "",  		   VTY_NEWLINE);  	if (IS_DEBUG_OSPF_PACKET (i, RECV))  	  vty_out (vty, "  OSPF packet %s receive%s debugging is on%s", -		   ospf_packet_type_str[i + 1], +		   LOOKUP (ospf_packet_type_str, i + 1),  		   IS_DEBUG_OSPF_PACKET (i, DETAIL) ? " detail" : "",  		   VTY_NEWLINE);        } diff --git a/ospfd/ospf_dump.h b/ospfd/ospf_dump.h index fb813719..a2d5e8ba 100644 --- a/ospfd/ospf_dump.h +++ b/ospfd/ospf_dump.h @@ -121,8 +121,9 @@ extern unsigned long term_debug_ospf_zebra;  extern unsigned long term_debug_ospf_nssa;  /* Message Strings. */ -extern const char *ospf_packet_type_str[];  extern char *ospf_lsa_type_str[]; +extern const struct message ospf_auth_type_str[]; +extern const size_t ospf_auth_type_str_max;  /* Prototypes. */  extern const char *ospf_area_name_string (struct ospf_area *); diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 77f2e161..2ebae89a 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -319,7 +319,8 @@ ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr,       procedure cannot overwrite the newly installed LSA until       MinLSArrival seconds have elapsed. */   -  new = ospf_lsa_install (ospf, nbr->oi, new); +  if (! (new = ospf_lsa_install (ospf, nbr->oi, new))) +    return -1; /* unknown LSA type or any other error condition */    /* Acknowledge the receipt of the LSA by sending a Link State       Acknowledgment packet back out the receiving interface. */ diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 842df49c..d5959eb1 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -746,7 +746,7 @@ ospf_stub_router_timer (struct thread *t)    return 0;  } -inline static void +static void  ospf_stub_router_check (struct ospf_area *area)  {    /* area must either be administratively configured to be stub @@ -1637,7 +1637,7 @@ ospf_external_lsa_new (struct ospf *ospf,    if (ei == NULL)      {        if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) -	zlog_debug ("LSA[Type5]: External info is NULL, could not originated"); +	zlog_debug ("LSA[Type5]: External info is NULL, can't originate");        return NULL;      } @@ -2838,9 +2838,9 @@ ospf_maxage_lsa_remover (struct thread *thread)            OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);          /* Remove LSA from the LSDB */ -        if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF)) +        if (IS_LSA_SELF (lsa))            if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) -            zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ", +            zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ",                         lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);          if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) @@ -3389,7 +3389,7 @@ ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)    /* This LSA is already checked. */    if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED)) -    return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF); +    return IS_LSA_SELF (lsa);    /* Make sure LSA is self-checked. */    SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED); @@ -3414,11 +3414,11 @@ ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)  	      {  		/* to make it easier later */  		SET_FLAG (lsa->flags, OSPF_LSA_SELF); -		return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF); +		return IS_LSA_SELF (lsa);  	      }        } -  return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF); +  return IS_LSA_SELF (lsa);  }  /* Get unique Link State ID. */ @@ -3541,6 +3541,7 @@ ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)    struct external_info *ei;    struct ospf_lsa *new = NULL;    assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF)); +  assert (IS_LSA_SELF (lsa));    assert (lsa->lock > 0);    switch (lsa->data->type) @@ -3589,7 +3590,7 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)    u_int16_t index, current_index;    assert (lsa->lock > 0); -  assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF)); +  assert (IS_LSA_SELF (lsa));    if (lsa->refresh_list < 0)      { @@ -3632,7 +3633,7 @@ void  ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)  {    assert (lsa->lock > 0); -  assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF)); +  assert (IS_LSA_SELF (lsa));    if (lsa->refresh_list >= 0)      {        struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list]; diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index 72e2f8a5..297cd984 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -49,6 +49,7 @@  #define OSPF_LSA_HEADER_SIZE	     20U  #define OSPF_ROUTER_LSA_LINK_SIZE    12U +#define OSPF_ROUTER_LSA_TOS_SIZE      4U  #define OSPF_MAX_LSA_SIZE	   1500U  /* AS-external-LSA refresh method. */ @@ -152,6 +153,7 @@ struct router_lsa_link  };  /* OSPF Router-LSAs structure. */ +#define OSPF_ROUTER_LSA_MIN_SIZE                  16U /* w/1 link descriptor */  struct router_lsa  {    struct lsa_header header; @@ -169,6 +171,7 @@ struct router_lsa  };  /* OSPF Network-LSAs structure. */ +#define OSPF_NETWORK_LSA_MIN_SIZE                  8U /* w/1 router-ID */  struct network_lsa  {    struct lsa_header header; @@ -177,6 +180,7 @@ struct network_lsa  };  /* OSPF Summary-LSAs structure. */ +#define OSPF_SUMMARY_LSA_MIN_SIZE                  8U /* w/1 TOS metric block */  struct summary_lsa  {    struct lsa_header header; @@ -186,6 +190,7 @@ struct summary_lsa  };  /* OSPF AS-external-LSAs structure. */ +#define OSPF_AS_EXTERNAL_LSA_MIN_SIZE             16U /* w/1 TOS forwarding block */  struct as_external_lsa  {    struct lsa_header header; @@ -274,6 +279,7 @@ extern struct in_addr ospf_get_ip_from_ifp (struct ospf_interface *);  extern struct ospf_lsa *ospf_external_lsa_originate (struct ospf *, struct external_info *);  extern int ospf_external_lsa_originate_timer (struct thread *); +extern int ospf_default_originate_timer (struct thread *);  extern struct ospf_lsa *ospf_lsa_lookup (struct ospf_area *, u_int32_t,  				  struct in_addr, struct in_addr);  extern struct ospf_lsa *ospf_lsa_lookup_by_id (struct ospf_area *, diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index 8b9a3458..bad674b6 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -38,6 +38,7 @@  #include "memory.h"  #include "privs.h"  #include "sigevent.h" +#include "zclient.h"  #include "ospfd/ospfd.h"  #include "ospfd/ospf_interface.h" @@ -80,6 +81,7 @@ struct option longopts[] =    { "daemon",      no_argument,       NULL, 'd'},    { "config_file", required_argument, NULL, 'f'},    { "pid_file",    required_argument, NULL, 'i'}, +  { "socket",      required_argument, NULL, 'z'},    { "dryrun",      no_argument,       NULL, 'C'},    { "help",        no_argument,       NULL, 'h'},    { "vty_addr",    required_argument, NULL, 'A'}, @@ -116,6 +118,7 @@ Daemon which manages OSPF.\n\n\  -d, --daemon       Runs in daemon mode\n\  -f, --config_file  Set configuration file name\n\  -i, --pid_file     Set process identifier file name\n\ +-z, --socket       Set path of zebra socket\n\  -A, --vty_addr     Set vty's bind address\n\  -P, --vty_port     Set vty's port number\n\  -u, --user         User to run as\n\ @@ -191,30 +194,11 @@ main (int argc, char **argv)    /* get program name */    progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]); -  /* Invoked by a priviledged user? -- endo. */ -  if (geteuid () != 0) -    { -      errno = EPERM; -      perror (progname); -      exit (1); -    } - -  zlog_default = openzlog (progname, ZLOG_OSPF, -			   LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON); - -  /* OSPF master init. */ -  ospf_master_init (); - -#ifdef SUPPORT_OSPF_API -  /* OSPF apiserver is disabled by default. */ -  ospf_apiserver_enable = 0; -#endif /* SUPPORT_OSPF_API */ -    while (1)       {        int opt; -      opt = getopt_long (argc, argv, "df:i:hA:P:u:g:avC", longopts, 0); +      opt = getopt_long (argc, argv, "df:i:z:hA:P:u:g:avC", longopts, 0);        if (opt == EOF)  	break; @@ -235,6 +219,9 @@ main (int argc, char **argv)          case 'i':            pid_file = optarg;            break; +	case 'z': +	  zclient_serv_path_set (optarg); +	  break;  	case 'P':            /* Deal with atoi() returning 0 on failure, and ospfd not               listening on ospfd port... */ @@ -274,6 +261,25 @@ main (int argc, char **argv)  	}      } +  /* Invoked by a priviledged user? -- endo. */ +  if (geteuid () != 0) +    { +      errno = EPERM; +      perror (progname); +      exit (1); +    } + +  zlog_default = openzlog (progname, ZLOG_OSPF, +			   LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON); + +  /* OSPF master init. */ +  ospf_master_init (); + +#ifdef SUPPORT_OSPF_API +  /* OSPF apiserver is disabled by default. */ +  ospf_apiserver_enable = 0; +#endif /* SUPPORT_OSPF_API */ +    /* Initializations. */    master = om->master; diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c index 1e2d44e6..3e326a8c 100644 --- a/ospfd/ospf_network.c +++ b/ospfd/ospf_network.c @@ -52,8 +52,8 @@ ospf_if_add_allspfrouters (struct ospf *top, struct prefix *p,  {    int ret; -  ret = setsockopt_multicast_ipv4 (top->fd, IP_ADD_MEMBERSHIP, -                                   p->u.prefix4, htonl (OSPF_ALLSPFROUTERS), +  ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP, +                                   htonl (OSPF_ALLSPFROUTERS),                                     ifindex);    if (ret < 0)      zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, " @@ -73,8 +73,8 @@ ospf_if_drop_allspfrouters (struct ospf *top, struct prefix *p,  {    int ret; -  ret = setsockopt_multicast_ipv4 (top->fd, IP_DROP_MEMBERSHIP, -                                   p->u.prefix4, htonl (OSPF_ALLSPFROUTERS), +  ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP, +                                   htonl (OSPF_ALLSPFROUTERS),                                     ifindex);    if (ret < 0)      zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, " @@ -94,8 +94,8 @@ ospf_if_add_alldrouters (struct ospf *top, struct prefix *p, unsigned int  {    int ret; -  ret = setsockopt_multicast_ipv4 (top->fd, IP_ADD_MEMBERSHIP, -                                   p->u.prefix4, htonl (OSPF_ALLDROUTERS), +  ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP, +                                   htonl (OSPF_ALLDROUTERS),                                     ifindex);    if (ret < 0)      zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, " @@ -115,8 +115,8 @@ ospf_if_drop_alldrouters (struct ospf *top, struct prefix *p, unsigned int  {    int ret; -  ret = setsockopt_multicast_ipv4 (top->fd, IP_DROP_MEMBERSHIP, -                                   p->u.prefix4, htonl (OSPF_ALLDROUTERS), +  ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP, +                                   htonl (OSPF_ALLDROUTERS),                                     ifindex);    if (ret < 0)      zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, " @@ -151,8 +151,7 @@ ospf_if_ipmulticast (struct ospf *top, struct prefix *p, unsigned int ifindex)      zlog_warn ("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s",  	       top->fd, safe_strerror (errno)); -  ret = setsockopt_multicast_ipv4 (top->fd, IP_MULTICAST_IF, -                                   p->u.prefix4, 0, ifindex); +  ret = setsockopt_ipv4_multicast_if (top->fd, ifindex);    if (ret < 0)      zlog_warn("can't setsockopt IP_MULTICAST_IF(fd %d, addr %s, "  	      "ifindex %u): %s", diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index be137d91..351fb210 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -50,16 +50,50 @@  #include "ospfd/ospf_dump.h"  /* Packet Type String. */ -const char *ospf_packet_type_str[] = -{ -  "unknown", -  "Hello", -  "Database Description", -  "Link State Request", -  "Link State Update", -  "Link State Acknowledgment", +const struct message ospf_packet_type_str[] = +{ +  { OSPF_MSG_HELLO,   "Hello"                     }, +  { OSPF_MSG_DB_DESC, "Database Description"      }, +  { OSPF_MSG_LS_REQ,  "Link State Request"        }, +  { OSPF_MSG_LS_UPD,  "Link State Update"         }, +  { OSPF_MSG_LS_ACK,  "Link State Acknowledgment" }, +}; +const size_t ospf_packet_type_str_max = sizeof (ospf_packet_type_str) / +  sizeof (ospf_packet_type_str[0]); + +/* Minimum (besides OSPF_HEADER_SIZE) lengths for OSPF packets of +   particular types, offset is the "type" field of a packet. */ +static const u_int16_t ospf_packet_minlen[] = +{ +  0, +  OSPF_HELLO_MIN_SIZE, +  OSPF_DB_DESC_MIN_SIZE, +  OSPF_LS_REQ_MIN_SIZE, +  OSPF_LS_UPD_MIN_SIZE, +  OSPF_LS_ACK_MIN_SIZE, +}; + +/* Minimum (besides OSPF_LSA_HEADER_SIZE) lengths for LSAs of particular +   types, offset is the "LSA type" field. */ +static const u_int16_t ospf_lsa_minlen[] = +{ +  0, +  OSPF_ROUTER_LSA_MIN_SIZE, +  OSPF_NETWORK_LSA_MIN_SIZE, +  OSPF_SUMMARY_LSA_MIN_SIZE, +  OSPF_SUMMARY_LSA_MIN_SIZE, +  OSPF_AS_EXTERNAL_LSA_MIN_SIZE, +  0, +  OSPF_AS_EXTERNAL_LSA_MIN_SIZE, +  0, +  0, +  0, +  0,  }; +/* for ospf_check_auth() */ +static int ospf_check_sum (struct ospf_header *); +  /* OSPF authentication checking function */  static int  ospf_auth_type (struct ospf_interface *oi) @@ -201,7 +235,7 @@ ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)  	       "destination %s) called with NULL obuf, ignoring "  	       "(please report this bug)!\n",  	       IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state), -	       ospf_packet_type_str[stream_getc_from(op->s, 1)], +	       LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),  	       inet_ntoa (op->dst));        return;      } @@ -222,7 +256,7 @@ ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op)  	       "destination %s) called with NULL obuf, ignoring "  	       "(please report this bug)!\n",  	       IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state), -	       ospf_packet_type_str[stream_getc_from(op->s, 1)], +	       LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)),  	       inet_ntoa (op->dst));        return;      } @@ -266,7 +300,7 @@ ospf_packet_dup (struct ospf_packet *op)  }  /* XXX inline */ -static inline unsigned int +static unsigned int  ospf_packet_authspace (struct ospf_interface *oi)  {    int auth = 0; @@ -291,24 +325,14 @@ ospf_packet_max (struct ospf_interface *oi)  static int -ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s, -                       u_int16_t length) +ospf_check_md5_digest (struct ospf_interface *oi, struct ospf_header *ospfh)  { -  unsigned char *ibuf;    MD5_CTX ctx;    unsigned char digest[OSPF_AUTH_MD5_SIZE]; -  unsigned char *pdigest;    struct crypt_key *ck; -  struct ospf_header *ospfh;    struct ospf_neighbor *nbr; +  u_int16_t length = ntohs (ospfh->length); - -  ibuf = STREAM_PNT (s); -  ospfh = (struct ospf_header *) ibuf; - -  /* Get pointer to the end of the packet. */ -  pdigest = ibuf + length; -    /* Get secret key. */    ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),  			      ospfh->u.crypt.key_id); @@ -334,12 +358,12 @@ ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,    /* Generate a digest for the ospf packet - their digest + our digest. */    memset(&ctx, 0, sizeof(ctx));    MD5Init(&ctx); -  MD5Update(&ctx, ibuf, length); +  MD5Update(&ctx, ospfh, length);    MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);    MD5Final(digest, &ctx);    /* compare the two */ -  if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE)) +  if (memcmp ((caddr_t)ospfh + length, digest, OSPF_AUTH_MD5_SIZE))      {        zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",  		 IF_NAME (oi)); @@ -755,7 +779,7 @@ ospf_write (struct thread *thread)  	}        zlog_debug ("%s sent to [%s] via [%s].", -		 ospf_packet_type_str[type], inet_ntoa (op->dst), +		 LOOKUP (ospf_packet_type_str, type), inet_ntoa (op->dst),  		 IF_NAME (oi));        if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL)) @@ -801,7 +825,7 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh,          {            zlog_debug ("ospf_header[%s/%s]: selforiginated, "                       "dropping.", -                     ospf_packet_type_str[ospfh->type], +                     LOOKUP (ospf_packet_type_str, ospfh->type),                       inet_ntoa (iph->ip_src));          }        return; @@ -1568,8 +1592,13 @@ ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,        sum = lsah->checksum;        if (sum != ospf_lsa_checksum (lsah))  	{ -	  zlog_warn ("Link State Update: LSA checksum error %x, %x.", -		     sum, lsah->checksum); +	  /* (bug #685) more details in a one-line message make it possible +	   * to identify problem source on the one hand and to have a better +	   * chance to compress repeated messages in syslog on the other */ +	  zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s", +		     sum, lsah->checksum, inet_ntoa (lsah->id), +		     inet_ntoa (nbr->src), inet_ntoa (nbr->router_id), +		     inet_ntoa (lsah->adv_router));  	  continue;  	} @@ -2116,7 +2145,7 @@ ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)    ip_len = iph->ip_len; -#if !defined(GNU_LINUX) && (OpenBSD < 200311) +#if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)    /*     * Kernel network code touches incoming IP header parameters,     * before protocol specific processing. @@ -2208,7 +2237,7 @@ ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,    return NULL;  } -static inline int +static int  ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)  {    /* Check match the Area ID of the receiving interface. */ @@ -2241,45 +2270,91 @@ ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)   return 0;  } +/* Return 1, if the packet is properly authenticated and checksummed, +   0 otherwise. In particular, check that AuType header field is valid and +   matches the locally configured AuType, and that D.5 requirements are met. */  static int -ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf, -		 struct ospf_header *ospfh) +ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh)  { -  int ret = 0;    struct crypt_key *ck; +  u_int16_t iface_auth_type; +  u_int16_t pkt_auth_type = ntohs (ospfh->auth_type); -  switch (ntohs (ospfh->auth_type)) +  switch (pkt_auth_type) +  { +  case OSPF_AUTH_NULL: /* RFC2328 D.5.1 */ +    if (OSPF_AUTH_NULL != (iface_auth_type = ospf_auth_type (oi)))      { -    case OSPF_AUTH_NULL: -      ret = 1; -      break; -    case OSPF_AUTH_SIMPLE: -      if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE)) -	ret = 1; -      else -	ret = 0; -      break; -    case OSPF_AUTH_CRYPTOGRAPHIC: -      if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL) -	{ -	  ret = 0; -	  break; -	} -       -      /* This is very basic, the digest processing is elsewhere */ -      if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&  -          ospfh->u.crypt.key_id == ck->key_id && -          ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf)) -        ret = 1; -      else -        ret = 0; -      break; -    default: -      ret = 0; -      break; +      if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) +        zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Null", +                   IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type)); +      return 0;      } - -  return ret; +    if (! ospf_check_sum (ospfh)) +    { +      if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) +        zlog_warn ("interface %s: Null auth OK, but checksum error, Router-ID %s", +                   IF_NAME (oi), inet_ntoa (ospfh->router_id)); +      return 0; +    } +    return 1; +  case OSPF_AUTH_SIMPLE: /* RFC2328 D.5.2 */ +    if (OSPF_AUTH_SIMPLE != (iface_auth_type = ospf_auth_type (oi))) +    { +      if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) +        zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Simple", +                   IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type)); +      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)) +        zlog_warn ("interface %s: Simple auth failed", IF_NAME (oi)); +      return 0; +    } +    if (! ospf_check_sum (ospfh)) +    { +      if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) +        zlog_warn ("interface %s: Simple auth OK, checksum error, Router-ID %s", +                   IF_NAME (oi), inet_ntoa (ospfh->router_id)); +      return 0; +    } +    return 1; +  case OSPF_AUTH_CRYPTOGRAPHIC: /* RFC2328 D.5.3 */ +    if (OSPF_AUTH_CRYPTOGRAPHIC != (iface_auth_type = ospf_auth_type (oi))) +    { +      if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) +        zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Cryptographic", +                   IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type)); +      return 0; +    } +    if (ospfh->checksum) +    { +      if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) +        zlog_warn ("interface %s: OSPF header checksum is not 0", IF_NAME (oi)); +      return 0; +    } +    /* only MD5 crypto method can pass ospf_packet_examin() */ +    if +    ( +      NULL == (ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) || +      ospfh->u.crypt.key_id != ck->key_id || +      /* Condition above uses the last key ID on the list, which is +         different from what ospf_crypt_key_lookup() does. A bug? */ +      ! ospf_check_md5_digest (oi, ospfh) +    ) +    { +      if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) +        zlog_warn ("interface %s: MD5 auth failed", IF_NAME (oi)); +      return 0; +    } +    return 1; +  default: +    if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) +      zlog_warn ("interface %s: invalid packet auth-type (%02x)", +                 IF_NAME (oi), pkt_auth_type); +    return 0; +  }  }  static int @@ -2308,19 +2383,311 @@ ospf_check_sum (struct ospf_header *ospfh)    return 1;  } +/* Verify, that given link/TOS records are properly sized/aligned and match +   Router-LSA "# links" and "# TOS" fields as specified in RFC2328 A.4.2. */ +static unsigned +ospf_router_lsa_links_examin +( +  struct router_lsa_link * link, +  u_int16_t linkbytes, +  const u_int16_t num_links +) +{ +  unsigned counted_links = 0, thislinklen; + +  while (linkbytes) +  { +    thislinklen = OSPF_ROUTER_LSA_LINK_SIZE + 4 * link->m[0].tos_count; +    if (thislinklen > linkbytes) +    { +      if (IS_DEBUG_OSPF_PACKET (0, RECV)) +        zlog_debug ("%s: length error in link block #%u", __func__, counted_links); +      return MSG_NG; +    } +    link = (struct router_lsa_link *)((caddr_t) link + thislinklen); +    linkbytes -= thislinklen; +    counted_links++; +  } +  if (counted_links != num_links) +  { +    if (IS_DEBUG_OSPF_PACKET (0, RECV)) +      zlog_debug ("%s: %u link blocks declared, %u present", +                  __func__, num_links, counted_links); +    return MSG_NG; +  } +  return MSG_OK; +} + +/* Verify, that the given LSA is properly sized/aligned (including type-specific +   minimum length constraint). */ +static unsigned +ospf_lsa_examin (struct lsa_header * lsah, const u_int16_t lsalen, const u_char headeronly) +{ +  unsigned ret; +  struct router_lsa * rlsa; +  if +  ( +    lsah->type < OSPF_MAX_LSA && +    ospf_lsa_minlen[lsah->type] && +    lsalen < OSPF_LSA_HEADER_SIZE + ospf_lsa_minlen[lsah->type] +  ) +  { +    if (IS_DEBUG_OSPF_PACKET (0, RECV)) +      zlog_debug ("%s: undersized (%u B) %s", +                  __func__, lsalen, LOOKUP (ospf_lsa_type_msg, lsah->type)); +    return MSG_NG; +  } +  switch (lsah->type) +  { +  case OSPF_ROUTER_LSA: +    /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1 (12+)-byte link blocks */ +    if (headeronly) +    { +      ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_ROUTER_LSA_MIN_SIZE) % 4 ? MSG_NG : MSG_OK; +      break; +    } +    rlsa = (struct router_lsa *) lsah; +    ret = ospf_router_lsa_links_examin +    ( +      (struct router_lsa_link *) rlsa->link, +      lsalen - OSPF_LSA_HEADER_SIZE - 4, /* skip: basic header, "flags", 0, "# links" */ +      ntohs (rlsa->links) /* 16 bits */ +    ); +    break; +  case OSPF_AS_EXTERNAL_LSA: +    /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long blocks */ +  case OSPF_AS_NSSA_LSA: +    /* RFC3101 C, idem */ +    ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_AS_EXTERNAL_LSA_MIN_SIZE) % 12 ? MSG_NG : MSG_OK; +    break; +  /* Following LSA types are considered OK length-wise as soon as their minimum +   * length constraint is met and length of the whole LSA is a multiple of 4 +   * (basic LSA header size is already a multiple of 4). */ +  case OSPF_NETWORK_LSA: +    /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */ +  case OSPF_SUMMARY_LSA: +  case OSPF_ASBR_SUMMARY_LSA: +    /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS blocks */ +#ifdef HAVE_OPAQUE_LSA +  case OSPF_OPAQUE_LINK_LSA: +  case OSPF_OPAQUE_AREA_LSA: +  case OSPF_OPAQUE_AS_LSA: +    /* RFC5250 A.2, "some number of octets (of application-specific +     * data) padded to 32-bit alignment." This is considered equivalent +     * to 4-byte alignment of all other LSA types, see OSPF-ALIGNMENT.txt +     * file for the detailed analysis of this passage. */ +#endif +    ret = lsalen % 4 ? MSG_NG : MSG_OK; +    break; +  default: +    if (IS_DEBUG_OSPF_PACKET (0, RECV)) +      zlog_debug ("%s: unsupported LSA type 0x%02x", __func__, lsah->type); +    return MSG_NG; +  } +  if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV)) +    zlog_debug ("%s: alignment error in %s", +                __func__, LOOKUP (ospf_lsa_type_msg, lsah->type)); +  return ret; +} + +/* Verify if the provided input buffer is a valid sequence of LSAs. This +   includes verification of LSA blocks length/alignment and dispatching +   of deeper-level checks. */ +static unsigned +ospf_lsaseq_examin +( +  struct lsa_header *lsah, /* start of buffered data */ +  size_t length, +  const u_char headeronly, +  /* When declared_num_lsas is not 0, compare it to the real number of LSAs +     and treat the difference as an error. */ +  const u_int32_t declared_num_lsas +) +{ +  u_int32_t counted_lsas = 0; + +  while (length) +  { +    u_int16_t lsalen; +    if (length < OSPF_LSA_HEADER_SIZE) +    { +      if (IS_DEBUG_OSPF_PACKET (0, RECV)) +        zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header", +                    __func__, length, counted_lsas); +      return MSG_NG; +    } +    /* save on ntohs() calls here and in the LSA validator */ +    lsalen = ntohs (lsah->length); +    if (lsalen < OSPF_LSA_HEADER_SIZE) +    { +      if (IS_DEBUG_OSPF_PACKET (0, RECV)) +        zlog_debug ("%s: malformed LSA header #%u, declared length is %u B", +                    __func__, counted_lsas, lsalen); +      return MSG_NG; +    } +    if (headeronly) +    { +      /* less checks here and in ospf_lsa_examin() */ +      if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 1)) +      { +        if (IS_DEBUG_OSPF_PACKET (0, RECV)) +          zlog_debug ("%s: malformed header-only LSA #%u", __func__, counted_lsas); +        return MSG_NG; +      } +      lsah = (struct lsa_header *) ((caddr_t) lsah + OSPF_LSA_HEADER_SIZE); +      length -= OSPF_LSA_HEADER_SIZE; +    } +    else +    { +      /* make sure the input buffer is deep enough before further checks */ +      if (lsalen > length) +      { +        if (IS_DEBUG_OSPF_PACKET (0, RECV)) +          zlog_debug ("%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B", +                      __func__, counted_lsas, lsalen, length); +        return MSG_NG; +      } +      if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 0)) +      { +        if (IS_DEBUG_OSPF_PACKET (0, RECV)) +          zlog_debug ("%s: malformed LSA #%u", __func__, counted_lsas); +        return MSG_NG; +      } +      lsah = (struct lsa_header *) ((caddr_t) lsah + lsalen); +      length -= lsalen; +    } +    counted_lsas++; +  } + +  if (declared_num_lsas && counted_lsas != declared_num_lsas) +  { +    if (IS_DEBUG_OSPF_PACKET (0, RECV)) +      zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)", +                  __func__, declared_num_lsas, counted_lsas); +    return MSG_NG; +  } +  return MSG_OK; +} + +/* Verify a complete OSPF packet for proper sizing/alignment. */ +static unsigned +ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire) +{ +  u_int16_t bytesdeclared, bytesauth; +  unsigned ret; +  struct ospf_ls_update * lsupd; + +  /* Length, 1st approximation. */ +  if (bytesonwire < OSPF_HEADER_SIZE) +  { +    if (IS_DEBUG_OSPF_PACKET (0, RECV)) +      zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire); +    return MSG_NG; +  } +  /* Now it is safe to access header fields. Performing length check, allow +   * for possible extra bytes of crypto auth/padding, which are not counted +   * in the OSPF header "length" field. */ +  if (oh->version != OSPF_VERSION) +  { +    if (IS_DEBUG_OSPF_PACKET (0, RECV)) +      zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version); +    return MSG_NG; +  } +  bytesdeclared = ntohs (oh->length); +  if (ntohs (oh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC) +    bytesauth = 0; +  else +  { +    if (oh->u.crypt.auth_data_len != OSPF_AUTH_MD5_SIZE) +    { +      if (IS_DEBUG_OSPF_PACKET (0, RECV)) +        zlog_debug ("%s: unsupported crypto auth length (%u B)", +                    __func__, oh->u.crypt.auth_data_len); +      return MSG_NG; +    } +    bytesauth = OSPF_AUTH_MD5_SIZE; +  } +  if (bytesdeclared + bytesauth > bytesonwire) +  { +    if (IS_DEBUG_OSPF_PACKET (0, RECV)) +      zlog_debug ("%s: packet length error (%u real, %u+%u declared)", +                  __func__, bytesonwire, bytesdeclared, bytesauth); +    return MSG_NG; +  } +  /* Length, 2nd approximation. The type-specific constraint is checked +     against declared length, not amount of bytes on wire. */ +  if +  ( +    oh->type >= OSPF_MSG_HELLO && +    oh->type <= OSPF_MSG_LS_ACK && +    bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type] +  ) +  { +    if (IS_DEBUG_OSPF_PACKET (0, RECV)) +      zlog_debug ("%s: undersized (%u B) %s packet", __func__, +                  bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type)); +    return MSG_NG; +  } +  switch (oh->type) +  { +  case OSPF_MSG_HELLO: +    /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes followed +       by N>=0 router-IDs. */ +    ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK; +    break; +  case OSPF_MSG_DB_DESC: +    /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes followed +       by N>=0 header-only LSAs. */ +    ret = ospf_lsaseq_examin +    ( +      (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE), +      bytesdeclared - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE, +      1, /* header-only LSAs */ +      0 +    ); +    break; +  case OSPF_MSG_LS_REQ: +    /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes request blocks. */ +    ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) % +      OSPF_LSA_KEY_SIZE ? MSG_NG : MSG_OK; +    break; +  case OSPF_MSG_LS_UPD: +    /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes followed +       by N>=0 full LSAs (with N declared beforehand). */ +    lsupd = (struct ospf_ls_update *) ((caddr_t) oh + OSPF_HEADER_SIZE); +    ret = ospf_lsaseq_examin +    ( +      (struct lsa_header *) ((caddr_t) lsupd + OSPF_LS_UPD_MIN_SIZE), +      bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE, +      0, /* full LSAs */ +      ntohl (lsupd->num_lsas) /* 32 bits */ +    ); +    break; +  case OSPF_MSG_LS_ACK: +    /* RFC2328 A.3.6, packet header followed by N>=0 header-only LSAs. */ +    ret = ospf_lsaseq_examin +    ( +      (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_LS_ACK_MIN_SIZE), +      bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE, +      1, /* header-only LSAs */ +      0 +    ); +    break; +  default: +    if (IS_DEBUG_OSPF_PACKET (0, RECV)) +      zlog_debug ("%s: invalid packet type 0x%02x", __func__, oh->type); +    return MSG_NG; +  } +  if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV)) +    zlog_debug ("%s: malformed %s packet", __func__, LOOKUP (ospf_packet_type_str, oh->type)); +  return ret; +} +  /* OSPF Header verification. */  static int  ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,  		    struct ip *iph, struct ospf_header *ospfh)  { -  /* check version. */ -  if (ospfh->version != OSPF_VERSION) -    { -      zlog_warn ("interface %s: ospf_read version number mismatch.", -		 IF_NAME (oi)); -      return -1; -    } -    /* Check Area ID. */    if (!ospf_check_area_id (oi, ospfh))      { @@ -2337,42 +2704,9 @@ ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,        return -1;      } -  /* Check authentication. */ -  if (ospf_auth_type (oi) != ntohs (ospfh->auth_type)) -    { -      zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d", -		 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type)); -      return -1; -    } - -  if (! ospf_check_auth (oi, ibuf, ospfh)) -    { -      zlog_warn ("interface %s: ospf_read authentication failed.", -		 IF_NAME (oi)); -      return -1; -    } - -  /* if check sum is invalid, packet is discarded. */ -  if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC) -    { -      if (! ospf_check_sum (ospfh)) -	{ -	  zlog_warn ("interface %s: ospf_read packet checksum error %s", -		     IF_NAME (oi), inet_ntoa (ospfh->router_id)); -	  return -1; -	} -    } -  else -    { -      if (ospfh->checksum != 0) -	return -1; -      if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0) -	{ -	  zlog_warn ("interface %s: ospf_read md5 authentication failed.", -		     IF_NAME (oi)); -	  return -1; -	} -    } +  /* Check authentication. The function handles logging actions, where required. */ +  if (! ospf_check_auth (oi, ospfh)) +    return -1;    return 0;  } @@ -2396,10 +2730,10 @@ ospf_read (struct thread *thread)    /* prepare for next packet. */    ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd); -  /* read OSPF packet. */    stream_reset(ospf->ibuf);    if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))      return -1; +  /* This raw packet is known to be at least as big as its IP header. */    /* Note that there should not be alignment problems with this assignment       because this is at the beginning of the stream data buffer. */ @@ -2430,15 +2764,23 @@ ospf_read (struct thread *thread)        return 0;      } -  /* Adjust size to message length. */ +  /* Advance from IP header to OSPF header (iph->ip_hl has been verified +     by ospf_recv_packet() to be correct). */    stream_forward_getp (ibuf, iph->ip_hl * 4); -   -  /* Get ospf packet header. */ +    ospfh = (struct ospf_header *) STREAM_PNT (ibuf); +  if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf))) +    return -1; +  /* Now it is safe to access all fields of OSPF packet header. */    /* associate packet with ospf interface */    oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp); +  /* ospf_verify_header() relies on a valid "oi" and thus can be called only +     after the passive/backbone/other checks below are passed. These checks +     in turn access the fields of unverified "ospfh" structure for their own +     purposes and must remain very accurate in doing this. */ +    /* If incoming interface is passive one, ignore it. */    if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)      { @@ -2529,6 +2871,17 @@ ospf_read (struct thread *thread)        return 0;      } +  /* Verify more OSPF header fields. */ +  ret = ospf_verify_header (ibuf, oi, iph, ospfh); +  if (ret < 0) +  { +    if (IS_DEBUG_OSPF_PACKET (0, RECV)) +      zlog_debug ("ospf_read[%s]: Header check failed, " +                  "dropping.", +                  inet_ntoa (iph->ip_src)); +    return ret; +  } +    /* Show debug receiving packet. */    if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))      { @@ -2539,7 +2892,7 @@ ospf_read (struct thread *thread)          }        zlog_debug ("%s received from [%s] via [%s]", -                 ospf_packet_type_str[ospfh->type], +                 LOOKUP (ospf_packet_type_str, ospfh->type),                   inet_ntoa (ospfh->router_id), IF_NAME (oi));        zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));        zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst)); @@ -2548,20 +2901,6 @@ ospf_read (struct thread *thread)  	zlog_debug ("-----------------------------------------------------");    } -  /* Some header verification. */ -  ret = ospf_verify_header (ibuf, oi, iph, ospfh); -  if (ret < 0) -    { -      if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) -        { -          zlog_debug ("ospf_read[%s/%s]: Header check failed, " -                     "dropping.", -                     ospf_packet_type_str[ospfh->type], -                     inet_ntoa (iph->ip_src)); -        } -      return ret; -    } -    stream_forward_getp (ibuf, OSPF_HEADER_SIZE);    /* Adjust size to message length. */ diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h index 9a472081..337686ad 100644 --- a/ospfd/ospf_packet.h +++ b/ospfd/ospf_packet.h @@ -46,6 +46,10 @@  #define OSPF_HELLO_REPLY_DELAY          1 +/* Return values of functions involved in packet verification, see ospf6d. */ +#define MSG_OK    0 +#define MSG_NG    1 +  struct ospf_packet  {    struct ospf_packet *next; @@ -117,6 +121,10 @@ struct ospf_db_desc    u_int32_t dd_seqnum;  }; +struct ospf_ls_update +{ +  u_int32_t num_lsas; +};  /* Macros. */  /* XXX Perhaps obsolete; function in ospf_packet.c */ @@ -163,4 +171,7 @@ extern int ospf_ls_ack_timer (struct thread *);  extern int ospf_poll_timer (struct thread *);  extern int ospf_hello_reply_timer (struct thread *); +extern const struct message ospf_packet_type_str[]; +extern const size_t ospf_packet_type_str_max; +  #endif /* _ZEBRA_OSPF_PACKET_H */ diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index 267237b8..d2e5e1e7 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -272,61 +272,6 @@ ospf_route_install (struct ospf *ospf, struct route_table *rt)        }  } -static void -ospf_intra_route_add (struct route_table *rt, struct vertex *v, -		      struct ospf_area *area) -{ -  struct route_node *rn; -  struct ospf_route *or; -  struct prefix_ipv4 p; -  struct ospf_path *path; -  struct vertex_parent *parent; -  struct listnode *node, *nnode; - -  p.family = AF_INET; -  p.prefix = v->id; -  if (v->type == OSPF_VERTEX_ROUTER) -    p.prefixlen = IPV4_MAX_BITLEN; -  else -    { -      struct network_lsa *lsa = (struct network_lsa *) v->lsa; -      p.prefixlen = ip_masklen (lsa->mask); -    } -  apply_mask_ipv4 (&p); - -  rn = route_node_get (rt, (struct prefix *) &p); -  if (rn->info) -    { -      zlog_warn ("Same routing information exists for %s", inet_ntoa (v->id)); -      route_unlock_node (rn); -      return; -    } - -  or = ospf_route_new (); - -  if (v->type == OSPF_VERTEX_NETWORK) -    { -      or->type = OSPF_DESTINATION_NETWORK; - -      for (ALL_LIST_ELEMENTS (v->parents, node, nnode, parent)) -        { -          path = ospf_path_new (); -          path->nexthop = parent->nexthop->router; -          listnode_add (or->paths, path); -        } -    } -  else -    or->type = OSPF_DESTINATION_ROUTER; - -  or->id = v->id; -  or->u.std.area_id = area->area_id; -  or->u.std.external_routing= area->external_routing; -  or->path_type = OSPF_PATH_INTRA_AREA; -  or->cost = v->distance; - -  rn->info = or; -} -  /* RFC2328 16.1. (4). For "router". */  void  ospf_intra_add_router (struct route_table *rt, struct vertex *v, @@ -720,10 +665,6 @@ ospf_asbr_route_cmp (struct ospf *ospf, struct ospf_route *r1,    r1_type = r1->path_type;    r2_type = r2->path_type; -  /* If RFC1583Compat flag is on -- all paths are equal. */ -  if (CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE)) -    return 0; -    /* r1/r2 itself is backbone, and it's Inter-area path. */    if (OSPF_IS_AREA_ID_BACKBONE (r1->u.std.area_id))      r1_type = OSPF_PATH_INTER_AREA; diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index ca200222..d7f9ba27 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -356,9 +356,6 @@ ospf_lsa_has_link (struct lsa_header *w, struct lsa_header *v)    return -1;  } -#define ROUTER_LSA_MIN_SIZE 12 -#define ROUTER_LSA_TOS_SIZE 4 -  /* Find the next link after prev_link from v to w.  If prev_link is   * NULL, return the first link from v to w.  Ignore stub and virtual links;   * these link types will never be returned. @@ -380,8 +377,8 @@ ospf_get_next_link (struct vertex *v, struct vertex *w,    else      {        p = (u_char *) prev_link; -      p += (ROUTER_LSA_MIN_SIZE + -            (prev_link->m[0].tos_count * ROUTER_LSA_TOS_SIZE)); +      p += (OSPF_ROUTER_LSA_LINK_SIZE + +            (prev_link->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE));      }    lim = ((u_char *) v->lsa) + ntohs (v->lsa->length); @@ -390,7 +387,7 @@ ospf_get_next_link (struct vertex *v, struct vertex *w,      {        l = (struct router_lsa_link *) p; -      p += (ROUTER_LSA_MIN_SIZE + (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE)); +      p += (OSPF_ROUTER_LSA_LINK_SIZE + (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE));        if (l->m[0].type != lsa_type)          continue; @@ -755,8 +752,8 @@ ospf_spf_next (struct vertex *v, struct ospf_area *area,          {            l = (struct router_lsa_link *) p; -          p += (ROUTER_LSA_MIN_SIZE + -                (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE)); +          p += (OSPF_ROUTER_LSA_LINK_SIZE + +                (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE));            /* (a) If this is a link to a stub network, examine the next               link in V's LSA.  Links to stub networks will be @@ -989,8 +986,8 @@ ospf_spf_process_stubs (struct ospf_area *area, struct vertex *v,          {            l = (struct router_lsa_link *) p; -          p += (ROUTER_LSA_MIN_SIZE + -                (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE)); +          p += (OSPF_ROUTER_LSA_LINK_SIZE + +                (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE));            if (l->m[0].type == LSA_LINK_TYPE_STUB)              ospf_intra_add_stub (rt, l, v, area, parent_is_root); @@ -1045,6 +1042,7 @@ ospf_rtrs_free (struct route_table *rtrs)    route_table_finish (rtrs);  } +#if 0  static void  ospf_rtrs_print (struct route_table *rtrs)  { @@ -1104,6 +1102,7 @@ ospf_rtrs_print (struct route_table *rtrs)    zlog_debug ("ospf_rtrs_print() end");  } +#endif  /* Calculating the shortest-path tree for an area. */  static void diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 46e7ffa5..97c8e8d6 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -80,8 +80,11 @@ ospf_str2area_id (const char *str, struct in_addr *area_id, int *format)    /* match "<0-4294967295>". */    else      { +      if (*str == '-') +        return -1; +      errno = 0;        ret = strtoul (str, &endptr, 10); -      if (*endptr != '\0' || (ret == ULONG_MAX && errno == ERANGE)) +      if (*endptr != '\0' || errno || ret > UINT32_MAX)          return -1;        area_id->s_addr = htonl (ret); @@ -93,29 +96,6 @@ ospf_str2area_id (const char *str, struct in_addr *area_id, int *format)  static int -str2distribute_source (const char *str, int *source) -{ -  /* Sanity check. */ -  if (str == NULL) -    return 0; - -  if (strncmp (str, "k", 1) == 0) -    *source = ZEBRA_ROUTE_KERNEL; -  else if (strncmp (str, "c", 1) == 0) -    *source = ZEBRA_ROUTE_CONNECT; -  else if (strncmp (str, "s", 1) == 0) -    *source = ZEBRA_ROUTE_STATIC; -  else if (strncmp (str, "r", 1) == 0) -    *source = ZEBRA_ROUTE_RIP; -  else if (strncmp (str, "b", 1) == 0) -    *source = ZEBRA_ROUTE_BGP; -  else -    return 0; - -  return 1; -} - -static int  str2metric (const char *str, int *metric)  {    /* Sanity check. */ @@ -3761,7 +3741,7 @@ show_as_external_lsa_detail (struct vty *vty, struct ospf_lsa *lsa)    return 0;  } -/* N.B. This function currently seems to be unused. */ +#if 0  static int  show_as_external_lsa_stdvty (struct ospf_lsa *lsa)  { @@ -3785,6 +3765,7 @@ show_as_external_lsa_stdvty (struct ospf_lsa *lsa)    return 0;  } +#endif  /* Show AS-NSSA-LSA detail information. */  static int @@ -5824,7 +5805,8 @@ DEFUN (ospf_redistribute_source_metric_type,    int metric = -1;    /* Get distribute source. */ -  if (!str2distribute_source (argv[0], &source)) +  source = proto_redistnum(AFI_IP, argv[0]); +  if (source < 0 || source == ZEBRA_ROUTE_OSPF)      return CMD_WARNING;    /* Get metric value. */ @@ -5885,7 +5867,8 @@ DEFUN (ospf_redistribute_source_type_metric,    int metric = -1;    /* Get distribute source. */ -  if (!str2distribute_source (argv[0], &source)) +  source = proto_redistnum(AFI_IP, argv[0]); +  if (source < 0 || source == ZEBRA_ROUTE_OSPF)      return CMD_WARNING;    /* Get metric value. */ @@ -5949,7 +5932,8 @@ DEFUN (ospf_redistribute_source_metric_routemap,    int metric = -1;    /* Get distribute source. */ -  if (!str2distribute_source (argv[0], &source)) +  source = proto_redistnum(AFI_IP, argv[0]); +  if (source < 0 || source == ZEBRA_ROUTE_OSPF)      return CMD_WARNING;    /* Get metric value. */ @@ -5982,7 +5966,8 @@ DEFUN (ospf_redistribute_source_type_routemap,    int type = -1;    /* Get distribute source. */ -  if (!str2distribute_source (argv[0], &source)) +  source = proto_redistnum(AFI_IP, argv[0]); +  if (source < 0 || source == ZEBRA_ROUTE_OSPF)      return CMD_WARNING;    /* Get metric value. */ @@ -6010,7 +5995,8 @@ DEFUN (ospf_redistribute_source_routemap,    int source;    /* Get distribute source. */ -  if (!str2distribute_source (argv[0], &source)) +  source = proto_redistnum(AFI_IP, argv[0]); +  if (source < 0 || source == ZEBRA_ROUTE_OSPF)      return CMD_WARNING;    if (argc == 2) @@ -6031,7 +6017,8 @@ DEFUN (no_ospf_redistribute_source,    struct ospf *ospf = vty->index;    int source; -  if (!str2distribute_source (argv[0], &source)) +  source = proto_redistnum(AFI_IP, argv[0]); +  if (source < 0 || source == ZEBRA_ROUTE_OSPF)      return CMD_WARNING;    ospf_routemap_unset (ospf, source); @@ -6050,7 +6037,8 @@ DEFUN (ospf_distribute_list_out,    int source;    /* Get distribute source. */ -  if (!str2distribute_source (argv[1], &source)) +  source = proto_redistnum(AFI_IP, argv[0]); +  if (source < 0 || source == ZEBRA_ROUTE_OSPF)      return CMD_WARNING;    return ospf_distribute_list_out_set (ospf, source, argv[0]); @@ -6068,7 +6056,8 @@ DEFUN (no_ospf_distribute_list_out,    struct ospf *ospf = vty->index;    int source; -  if (!str2distribute_source (argv[1], &source)) +  source = proto_redistnum(AFI_IP, argv[0]); +  if (source < 0 || source == ZEBRA_ROUTE_OSPF)      return CMD_WARNING;    return ospf_distribute_list_out_unset (ospf, source, argv[0]); @@ -7902,9 +7891,9 @@ config_write_ospf_distribute (struct vty *vty, struct ospf *ospf)      {        /* distribute-list print. */        for (type = 0; type < ZEBRA_ROUTE_MAX; type++) -	if (ospf->dlist[type].name) +	if (DISTRIBUTE_NAME (ospf, type))  	  vty_out (vty, " distribute-list %s out %s%s",  -		   ospf->dlist[type].name, +		   DISTRIBUTE_NAME (ospf, type),  		   zebra_route_string(type), VTY_NEWLINE);        /* default-information print. */ diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 50ca85e1..f8d1cb7c 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -358,6 +358,7 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)        stream_putc (s, ZEBRA_ROUTE_OSPF);        stream_putc (s, flags);        stream_putc (s, message); +      stream_putw (s, SAFI_UNICAST);        /* Put prefix information. */        psize = PSIZE (p->prefixlen); @@ -427,6 +428,7 @@ ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)        api.type = ZEBRA_ROUTE_OSPF;        api.flags = 0;        api.message = 0; +      api.safi = SAFI_UNICAST;        api.ifindex_num = 0;        api.nexthop_num = 0; @@ -483,6 +485,7 @@ ospf_zebra_add_discard (struct prefix_ipv4 *p)        api.type = ZEBRA_ROUTE_OSPF;        api.flags = ZEBRA_FLAG_BLACKHOLE;        api.message = 0; +      api.safi = SAFI_UNICAST;        SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);        api.nexthop_num = 0;        api.ifindex_num = 0; @@ -505,6 +508,7 @@ ospf_zebra_delete_discard (struct prefix_ipv4 *p)        api.type = ZEBRA_ROUTE_OSPF;        api.flags = ZEBRA_FLAG_BLACKHOLE;        api.message = 0; +      api.safi = SAFI_UNICAST;        SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);        api.nexthop_num = 0;        api.ifindex_num = 0; @@ -670,7 +674,7 @@ ospf_external_lsa_originate_check (struct ospf *ospf,    if (is_prefix_default (&ei->p))      if (ospf->default_originate == DEFAULT_ORIGINATE_NONE)        { -        zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-exntenal-LSA " +        zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-external-LSA "                     "for default");          return 0;        } diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h index 3efd8958..fbb34442 100644 --- a/ospfd/ospf_zebra.h +++ b/ospfd/ospf_zebra.h @@ -50,8 +50,6 @@ extern void ospf_zebra_delete (struct prefix_ipv4 *, struct ospf_route *);  extern void ospf_zebra_add_discard (struct prefix_ipv4 *);  extern void ospf_zebra_delete_discard (struct prefix_ipv4 *); -extern int ospf_default_originate_timer (struct thread *); -  extern int ospf_redistribute_check (struct ospf *, struct external_info *,  				    int *);  extern int ospf_distribute_check_connected (struct ospf *, diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 0188ffda..e8405136 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -1204,6 +1204,7 @@ ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,    return 1;  } +#if 0  /* XXX: unused? Leave for symmetry? */  static int  ospf_area_nssa_translator_role_unset (struct ospf *ospf, @@ -1221,6 +1222,7 @@ ospf_area_nssa_translator_role_unset (struct ospf *ospf,    return 1;  } +#endif  int  ospf_area_export_list_set (struct ospf *ospf, diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 0e57c452..7a56d163 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -72,10 +72,6 @@  #define OSPF_ALLSPFROUTERS              0xe0000005      /* 224.0.0.5 */  #define OSPF_ALLDROUTERS                0xe0000006      /* 224.0.0.6 */ -/* XXX Where is this used? And why it was used only if compiled with - * NSSA support. */ -#define OSPF_LOOPer                     0x7f000000      /* 127.0.0.0 */ -  #define OSPF_AREA_BACKBONE              0x00000000      /* 0.0.0.0 */  /* OSPF Authentication Type. */ | 
