File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospf_api.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:54:40 2013 UTC (10 years, 11 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, HEAD
0.99.22

    1: /*
    2:  * API message handling module for OSPF daemon and client.
    3:  * Copyright (C) 2001, 2002 Ralph Keller
    4:  *
    5:  * This file is part of GNU Zebra.
    6:  * 
    7:  * GNU Zebra is free software; you can redistribute it and/or modify
    8:  * it under the terms of the GNU General Public License as published
    9:  * by the Free Software Foundation; either version 2, or (at your
   10:  * option) any later version.
   11:  *
   12:  * GNU Zebra is distributed in the hope that it will be useful, but
   13:  * WITHOUT ANY WARRANTY; without even the implied warranty of
   14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15:  * General Public License for more details.
   16:  *
   17:  * You should have received a copy of the GNU General Public License
   18:  * along with GNU Zebra; see the file COPYING.  If not, write to the
   19:  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   20:  * Boston, MA 02111-1307, USA.
   21:  */
   22: 
   23: #include <zebra.h>
   24: 
   25: #ifdef SUPPORT_OSPF_API
   26: #ifndef HAVE_OPAQUE_LSA
   27: #error "Core Opaque-LSA module must be configured."
   28: #endif /* HAVE_OPAQUE_LSA */
   29: 
   30: #include "linklist.h"
   31: #include "prefix.h"
   32: #include "if.h"
   33: #include "table.h"
   34: #include "memory.h"
   35: #include "command.h"
   36: #include "vty.h"
   37: #include "stream.h"
   38: #include "log.h"
   39: #include "thread.h"
   40: #include "hash.h"
   41: #include "sockunion.h"		/* for inet_aton() */
   42: #include "buffer.h"
   43: #include "network.h"
   44: 
   45: #include "ospfd/ospfd.h"
   46: #include "ospfd/ospf_interface.h"
   47: #include "ospfd/ospf_ism.h"
   48: #include "ospfd/ospf_asbr.h"
   49: #include "ospfd/ospf_lsa.h"
   50: #include "ospfd/ospf_lsdb.h"
   51: #include "ospfd/ospf_neighbor.h"
   52: #include "ospfd/ospf_nsm.h"
   53: #include "ospfd/ospf_flood.h"
   54: #include "ospfd/ospf_packet.h"
   55: #include "ospfd/ospf_spf.h"
   56: #include "ospfd/ospf_dump.h"
   57: #include "ospfd/ospf_route.h"
   58: #include "ospfd/ospf_ase.h"
   59: #include "ospfd/ospf_zebra.h"
   60: 
   61: #include "ospfd/ospf_api.h"
   62: 
   63: 
   64: /* For debugging only, will be removed */
   65: void
   66: api_opaque_lsa_print (struct lsa_header *data)
   67: {
   68:   struct opaque_lsa
   69:   {
   70:     struct lsa_header header;
   71:     u_char mydata[];
   72:   };
   73: 
   74:   struct opaque_lsa *olsa;
   75:   int opaquelen;
   76:   int i;
   77: 
   78:   ospf_lsa_header_dump (data);
   79: 
   80:   olsa = (struct opaque_lsa *) data;
   81: 
   82:   opaquelen = ntohs (data->length) - OSPF_LSA_HEADER_SIZE;
   83:   zlog_debug ("apiserver_lsa_print: opaquelen=%d\n", opaquelen);
   84: 
   85:   for (i = 0; i < opaquelen; i++)
   86:     {
   87:       zlog_debug ("0x%x ", olsa->mydata[i]);
   88:     }
   89:   zlog_debug ("\n");
   90: }
   91: 
   92: /* -----------------------------------------------------------
   93:  * Generic messages
   94:  * -----------------------------------------------------------
   95:  */
   96: 
   97: struct msg *
   98: msg_new (u_char msgtype, void *msgbody, u_int32_t seqnum, u_int16_t msglen)
   99: {
  100:   struct msg *new;
  101: 
  102:   new = XCALLOC (MTYPE_OSPF_API_MSG, sizeof (struct msg));
  103: 
  104:   new->hdr.version = OSPF_API_VERSION;
  105:   new->hdr.msgtype = msgtype;
  106:   new->hdr.msglen = htons (msglen);
  107:   new->hdr.msgseq = htonl (seqnum);
  108: 
  109:   new->s = stream_new (msglen);
  110:   assert (new->s);
  111:   stream_put (new->s, msgbody, msglen);
  112: 
  113:   return new;
  114: }
  115: 
  116: 
  117: /* Duplicate a message by copying content. */
  118: struct msg *
  119: msg_dup (struct msg *msg)
  120: {
  121:   struct msg *new;
  122: 
  123:   assert (msg);
  124: 
  125:   new = msg_new (msg->hdr.msgtype, STREAM_DATA (msg->s),
  126: 		 ntohl (msg->hdr.msgseq), ntohs (msg->hdr.msglen));
  127:   return new;
  128: }
  129: 
  130: 
  131: /* XXX only for testing, will be removed */
  132: 
  133: struct nametab {
  134:   int value;
  135:   const char *name;
  136: };
  137: 
  138: const char *
  139: ospf_api_typename (int msgtype)
  140: {
  141:   struct nametab NameTab[] = {
  142:     { MSG_REGISTER_OPAQUETYPE,   "Register opaque-type",   },
  143:     { MSG_UNREGISTER_OPAQUETYPE, "Unregister opaque-type", },
  144:     { MSG_REGISTER_EVENT,        "Register event",         },
  145:     { MSG_SYNC_LSDB,             "Sync LSDB",              },
  146:     { MSG_ORIGINATE_REQUEST,     "Originate request",      },
  147:     { MSG_DELETE_REQUEST,        "Delete request",         },
  148:     { MSG_REPLY,                 "Reply",                  },
  149:     { MSG_READY_NOTIFY,          "Ready notify",           },
  150:     { MSG_LSA_UPDATE_NOTIFY,     "LSA update notify",      },
  151:     { MSG_LSA_DELETE_NOTIFY,     "LSA delete notify",      },
  152:     { MSG_NEW_IF,                "New interface",          },
  153:     { MSG_DEL_IF,                "Del interface",          },
  154:     { MSG_ISM_CHANGE,            "ISM change",             },
  155:     { MSG_NSM_CHANGE,            "NSM change",             },
  156:   };
  157: 
  158:   int i, n = array_size(NameTab);
  159:   const char *name = NULL;
  160: 
  161:   for (i = 0; i < n; i++)
  162:     {
  163:       if (NameTab[i].value == msgtype)
  164:         {
  165:           name = NameTab[i].name;
  166:           break;
  167:         }
  168:     }
  169: 
  170:   return name ? name : "?";
  171: }
  172: 
  173: const char *
  174: ospf_api_errname (int errcode)
  175: {
  176:   struct nametab NameTab[] = {
  177:     { OSPF_API_OK,                      "OK",                         },
  178:     { OSPF_API_NOSUCHINTERFACE,         "No such interface",          },
  179:     { OSPF_API_NOSUCHAREA,              "No such area",               },
  180:     { OSPF_API_NOSUCHLSA,               "No such LSA",                },
  181:     { OSPF_API_ILLEGALLSATYPE,          "Illegal LSA type",           },
  182:     { OSPF_API_OPAQUETYPEINUSE,         "Opaque type in use",         },
  183:     { OSPF_API_OPAQUETYPENOTREGISTERED, "Opaque type not registered", },
  184:     { OSPF_API_NOTREADY,                "Not ready",                  },
  185:     { OSPF_API_NOMEMORY,                "No memory",                  },
  186:     { OSPF_API_ERROR,                   "Other error",                },
  187:     { OSPF_API_UNDEF,                   "Undefined",                  },
  188:   };
  189: 
  190:   int i, n = array_size(NameTab);
  191:   const char *name = NULL;
  192: 
  193:   for (i = 0; i < n; i++)
  194:     {
  195:       if (NameTab[i].value == errcode)
  196:         {
  197:           name = NameTab[i].name;
  198:           break;
  199:         }
  200:     }
  201: 
  202:   return name ? name : "?";
  203: }
  204: 
  205: void
  206: msg_print (struct msg *msg)
  207: {
  208:   if (!msg)
  209:     {
  210:       zlog_debug ("msg_print msg=NULL!\n");
  211:       return;
  212:     }
  213: 
  214: #ifdef ORIGINAL_CODING
  215:   zlog_debug
  216:     ("msg=%p msgtype=%d msglen=%d msgseq=%d streamdata=%p streamsize=%lu\n",
  217:      msg, msg->hdr.msgtype, ntohs (msg->hdr.msglen), ntohl (msg->hdr.msgseq),
  218:      STREAM_DATA (msg->s), STREAM_SIZE (msg->s));
  219: #else /* ORIGINAL_CODING */
  220:   /* API message common header part. */
  221:   zlog_debug
  222:     ("API-msg [%s]: type(%d),len(%d),seq(%lu),data(%p),size(%zd)",
  223:      ospf_api_typename (msg->hdr.msgtype), msg->hdr.msgtype, 
  224:      ntohs (msg->hdr.msglen), (unsigned long) ntohl (msg->hdr.msgseq),
  225:      STREAM_DATA (msg->s), STREAM_SIZE (msg->s));
  226: 
  227:   /* API message body part. */
  228: #ifdef ndef
  229:   /* Generic Hex/Ascii dump */
  230:   DumpBuf (STREAM_DATA (msg->s), STREAM_SIZE (msg->s)); /* Sorry, deleted! */
  231: #else /* ndef */
  232:   /* Message-type dependent dump function. */
  233: #endif /* ndef */
  234: 
  235:   return;
  236: #endif /* ORIGINAL_CODING */
  237: }
  238: 
  239: void
  240: msg_free (struct msg *msg)
  241: {
  242:   if (msg->s)
  243:     stream_free (msg->s);
  244: 
  245:   XFREE (MTYPE_OSPF_API_MSG, msg);
  246: }
  247: 
  248: 
  249: /* Set sequence number of message */
  250: void
  251: msg_set_seq (struct msg *msg, u_int32_t seqnr)
  252: {
  253:   assert (msg);
  254:   msg->hdr.msgseq = htonl (seqnr);
  255: }
  256: 
  257: /* Get sequence number of message */
  258: u_int32_t
  259: msg_get_seq (struct msg *msg)
  260: {
  261:   assert (msg);
  262:   return ntohl (msg->hdr.msgseq);
  263: }
  264: 
  265: /* -----------------------------------------------------------
  266:  * Message fifo queues
  267:  * -----------------------------------------------------------
  268:  */
  269: 
  270: struct msg_fifo *
  271: msg_fifo_new ()
  272: {
  273:   return XCALLOC (MTYPE_OSPF_API_FIFO, sizeof (struct msg_fifo));
  274: }
  275: 
  276: /* Add new message to fifo. */
  277: void
  278: msg_fifo_push (struct msg_fifo *fifo, struct msg *msg)
  279: {
  280:   if (fifo->tail)
  281:     fifo->tail->next = msg;
  282:   else
  283:     fifo->head = msg;
  284: 
  285:   fifo->tail = msg;
  286:   fifo->count++;
  287: }
  288: 
  289: 
  290: /* Remove first message from fifo. */
  291: struct msg *
  292: msg_fifo_pop (struct msg_fifo *fifo)
  293: {
  294:   struct msg *msg;
  295: 
  296:   msg = fifo->head;
  297:   if (msg)
  298:     {
  299:       fifo->head = msg->next;
  300: 
  301:       if (fifo->head == NULL)
  302: 	fifo->tail = NULL;
  303: 
  304:       fifo->count--;
  305:     }
  306:   return msg;
  307: }
  308: 
  309: /* Return first fifo entry but do not remove it. */
  310: struct msg *
  311: msg_fifo_head (struct msg_fifo *fifo)
  312: {
  313:   return fifo->head;
  314: }
  315: 
  316: /* Flush message fifo. */
  317: void
  318: msg_fifo_flush (struct msg_fifo *fifo)
  319: {
  320:   struct msg *op;
  321:   struct msg *next;
  322: 
  323:   for (op = fifo->head; op; op = next)
  324:     {
  325:       next = op->next;
  326:       msg_free (op);
  327:     }
  328: 
  329:   fifo->head = fifo->tail = NULL;
  330:   fifo->count = 0;
  331: }
  332: 
  333: /* Free API message fifo. */
  334: void
  335: msg_fifo_free (struct msg_fifo *fifo)
  336: {
  337:   msg_fifo_flush (fifo);
  338: 
  339:   XFREE (MTYPE_OSPF_API_FIFO, fifo);
  340: }
  341: 
  342: struct msg *
  343: msg_read (int fd)
  344: {
  345:   struct msg *msg;
  346:   struct apimsghdr hdr;
  347:   u_char buf[OSPF_API_MAX_MSG_SIZE];
  348:   int bodylen;
  349:   int rlen;
  350: 
  351:   /* Read message header */
  352:   rlen = readn (fd, (u_char *) &hdr, sizeof (struct apimsghdr));
  353: 
  354:   if (rlen < 0)
  355:     {
  356:       zlog_warn ("msg_read: readn %s", safe_strerror (errno));
  357:       return NULL;
  358:     }
  359:   else if (rlen == 0)
  360:     {
  361:       zlog_warn ("msg_read: Connection closed by peer");
  362:       return NULL;
  363:     }
  364:   else if (rlen != sizeof (struct apimsghdr))
  365:     {
  366:       zlog_warn ("msg_read: Cannot read message header!");
  367:       return NULL;
  368:     }
  369: 
  370:   /* Check version of API protocol */
  371:   if (hdr.version != OSPF_API_VERSION)
  372:     {
  373:       zlog_warn ("msg_read: OSPF API protocol version mismatch");
  374:       return NULL;
  375:     }
  376: 
  377:   /* Determine body length. */
  378:   bodylen = ntohs (hdr.msglen);
  379:   if (bodylen > 0)
  380:     {
  381: 
  382:       /* Read message body */
  383:       rlen = readn (fd, buf, bodylen);
  384:       if (rlen < 0)
  385: 	{
  386: 	  zlog_warn ("msg_read: readn %s", safe_strerror (errno));
  387: 	  return NULL;
  388: 	}
  389:       else if (rlen == 0)
  390: 	{
  391: 	  zlog_warn ("msg_read: Connection closed by peer");
  392: 	  return NULL;
  393: 	}
  394:       else if (rlen != bodylen)
  395: 	{
  396: 	  zlog_warn ("msg_read: Cannot read message body!");
  397: 	  return NULL;
  398: 	}
  399:     }
  400: 
  401:   /* Allocate new message */
  402:   msg = msg_new (hdr.msgtype, buf, ntohl (hdr.msgseq), ntohs (hdr.msglen));
  403: 
  404:   return msg;
  405: }
  406: 
  407: int
  408: msg_write (int fd, struct msg *msg)
  409: {
  410:   u_char buf[OSPF_API_MAX_MSG_SIZE];
  411:   int l;
  412:   int wlen;
  413: 
  414:   assert (msg);
  415:   assert (msg->s);
  416: 
  417:   /* Length of message including header */
  418:   l = sizeof (struct apimsghdr) + ntohs (msg->hdr.msglen);
  419: 
  420:   /* Make contiguous memory buffer for message */
  421:   memcpy (buf, &msg->hdr, sizeof (struct apimsghdr));
  422:   memcpy (buf + sizeof (struct apimsghdr), STREAM_DATA (msg->s),
  423: 	  ntohs (msg->hdr.msglen));
  424: 
  425:   wlen = writen (fd, buf, l);
  426:   if (wlen < 0)
  427:     {
  428:       zlog_warn ("msg_write: writen %s", safe_strerror (errno));
  429:       return -1;
  430:     }
  431:   else if (wlen == 0)
  432:     {
  433:       zlog_warn ("msg_write: Connection closed by peer");
  434:       return -1;
  435:     }
  436:   else if (wlen != l)
  437:     {
  438:       zlog_warn ("msg_write: Cannot write API message");
  439:       return -1;
  440:     }
  441:   return 0;
  442: }
  443: 
  444: /* -----------------------------------------------------------
  445:  * Specific messages
  446:  * -----------------------------------------------------------
  447:  */
  448: 
  449: struct msg *
  450: new_msg_register_opaque_type (u_int32_t seqnum, u_char ltype, u_char otype)
  451: {
  452:   struct msg_register_opaque_type rmsg;
  453: 
  454:   rmsg.lsatype = ltype;
  455:   rmsg.opaquetype = otype;
  456:   memset (&rmsg.pad, 0, sizeof (rmsg.pad));
  457: 
  458:   return msg_new (MSG_REGISTER_OPAQUETYPE, &rmsg, seqnum,
  459: 		  sizeof (struct msg_register_opaque_type));
  460: }
  461: 
  462: struct msg *
  463: new_msg_register_event (u_int32_t seqnum, struct lsa_filter_type *filter)
  464: {
  465:   u_char buf[OSPF_API_MAX_MSG_SIZE];
  466:   struct msg_register_event *emsg;
  467:   int len;
  468: 
  469:   emsg = (struct msg_register_event *) buf;
  470:   len = sizeof (struct msg_register_event) +
  471:     filter->num_areas * sizeof (struct in_addr);
  472:   emsg->filter.typemask = htons (filter->typemask);
  473:   emsg->filter.origin = filter->origin;
  474:   emsg->filter.num_areas = filter->num_areas;
  475:   return msg_new (MSG_REGISTER_EVENT, emsg, seqnum, len);
  476: }
  477: 
  478: struct msg *
  479: new_msg_sync_lsdb (u_int32_t seqnum, struct lsa_filter_type *filter)
  480: {
  481:   u_char buf[OSPF_API_MAX_MSG_SIZE];
  482:   struct msg_sync_lsdb *smsg;
  483:   int len;
  484: 
  485:   smsg = (struct msg_sync_lsdb *) buf;
  486:   len = sizeof (struct msg_sync_lsdb) +
  487:     filter->num_areas * sizeof (struct in_addr);
  488:   smsg->filter.typemask = htons (filter->typemask);
  489:   smsg->filter.origin = filter->origin;
  490:   smsg->filter.num_areas = filter->num_areas;
  491:   return msg_new (MSG_SYNC_LSDB, smsg, seqnum, len);
  492: }
  493: 
  494: 
  495: struct msg *
  496: new_msg_originate_request (u_int32_t seqnum,
  497: 			   struct in_addr ifaddr,
  498: 			   struct in_addr area_id, struct lsa_header *data)
  499: {
  500:   struct msg_originate_request *omsg;
  501:   int omsglen;
  502:   char buf[OSPF_API_MAX_MSG_SIZE];
  503: 
  504:   omsglen = sizeof (struct msg_originate_request) - sizeof (struct lsa_header)
  505:     + ntohs (data->length);
  506: 
  507:   omsg = (struct msg_originate_request *) buf;
  508:   omsg->ifaddr = ifaddr;
  509:   omsg->area_id = area_id;
  510:   memcpy (&omsg->data, data, ntohs (data->length));
  511: 
  512:   return msg_new (MSG_ORIGINATE_REQUEST, omsg, seqnum, omsglen);
  513: }
  514: 
  515: struct msg *
  516: new_msg_delete_request (u_int32_t seqnum,
  517: 			struct in_addr area_id, u_char lsa_type,
  518: 			u_char opaque_type, u_int32_t opaque_id)
  519: {
  520:   struct msg_delete_request dmsg;
  521:   dmsg.area_id = area_id;
  522:   dmsg.lsa_type = lsa_type;
  523:   dmsg.opaque_type = opaque_type;
  524:   dmsg.opaque_id = htonl (opaque_id);
  525:   memset (&dmsg.pad, 0, sizeof (dmsg.pad));
  526: 
  527:   return msg_new (MSG_DELETE_REQUEST, &dmsg, seqnum,
  528: 		  sizeof (struct msg_delete_request));
  529: }
  530: 
  531: 
  532: struct msg *
  533: new_msg_reply (u_int32_t seqnr, u_char rc)
  534: {
  535:   struct msg *msg;
  536:   struct msg_reply rmsg;
  537: 
  538:   /* Set return code */
  539:   rmsg.errcode = rc;
  540:   memset (&rmsg.pad, 0, sizeof (rmsg.pad));
  541: 
  542:   msg = msg_new (MSG_REPLY, &rmsg, seqnr, sizeof (struct msg_reply));
  543: 
  544:   return msg;
  545: }
  546: 
  547: struct msg *
  548: new_msg_ready_notify (u_int32_t seqnr, u_char lsa_type,
  549: 		      u_char opaque_type, struct in_addr addr)
  550: {
  551:   struct msg_ready_notify rmsg;
  552: 
  553:   rmsg.lsa_type = lsa_type;
  554:   rmsg.opaque_type = opaque_type;
  555:   memset (&rmsg.pad, 0, sizeof (rmsg.pad));
  556:   rmsg.addr = addr;
  557: 
  558:   return msg_new (MSG_READY_NOTIFY, &rmsg, seqnr,
  559: 		  sizeof (struct msg_ready_notify));
  560: }
  561: 
  562: struct msg *
  563: new_msg_new_if (u_int32_t seqnr,
  564: 		struct in_addr ifaddr, struct in_addr area_id)
  565: {
  566:   struct msg_new_if nmsg;
  567: 
  568:   nmsg.ifaddr = ifaddr;
  569:   nmsg.area_id = area_id;
  570: 
  571:   return msg_new (MSG_NEW_IF, &nmsg, seqnr, sizeof (struct msg_new_if));
  572: }
  573: 
  574: struct msg *
  575: new_msg_del_if (u_int32_t seqnr, struct in_addr ifaddr)
  576: {
  577:   struct msg_del_if dmsg;
  578: 
  579:   dmsg.ifaddr = ifaddr;
  580: 
  581:   return msg_new (MSG_DEL_IF, &dmsg, seqnr, sizeof (struct msg_del_if));
  582: }
  583: 
  584: struct msg *
  585: new_msg_ism_change (u_int32_t seqnr, struct in_addr ifaddr,
  586: 		    struct in_addr area_id, u_char status)
  587: {
  588:   struct msg_ism_change imsg;
  589: 
  590:   imsg.ifaddr = ifaddr;
  591:   imsg.area_id = area_id;
  592:   imsg.status = status;
  593:   memset (&imsg.pad, 0, sizeof (imsg.pad));
  594: 
  595:   return msg_new (MSG_ISM_CHANGE, &imsg, seqnr,
  596: 		  sizeof (struct msg_ism_change));
  597: }
  598: 
  599: struct msg *
  600: new_msg_nsm_change (u_int32_t seqnr, struct in_addr ifaddr,
  601: 		    struct in_addr nbraddr,
  602: 		    struct in_addr router_id, u_char status)
  603: {
  604:   struct msg_nsm_change nmsg;
  605: 
  606:   nmsg.ifaddr = ifaddr;
  607:   nmsg.nbraddr = nbraddr;
  608:   nmsg.router_id = router_id;
  609:   nmsg.status = status;
  610:   memset (&nmsg.pad, 0, sizeof (nmsg.pad));
  611: 
  612:   return msg_new (MSG_NSM_CHANGE, &nmsg, seqnr,
  613: 		  sizeof (struct msg_nsm_change));
  614: }
  615: 
  616: struct msg *
  617: new_msg_lsa_change_notify (u_char msgtype,
  618: 			   u_int32_t seqnum,
  619: 			   struct in_addr ifaddr,
  620: 			   struct in_addr area_id,
  621: 			   u_char is_self_originated, struct lsa_header *data)
  622: {
  623:   u_char buf[OSPF_API_MAX_MSG_SIZE];
  624:   struct msg_lsa_change_notify *nmsg;
  625:   int len;
  626: 
  627:   assert (data);
  628: 
  629:   nmsg = (struct msg_lsa_change_notify *) buf;
  630:   len = ntohs (data->length) + sizeof (struct msg_lsa_change_notify)
  631:     - sizeof (struct lsa_header);
  632:   nmsg->ifaddr = ifaddr;
  633:   nmsg->area_id = area_id;
  634:   nmsg->is_self_originated = is_self_originated;
  635:   memset (&nmsg->pad, 0, sizeof (nmsg->pad));
  636:   memcpy (&nmsg->data, data, ntohs (data->length));
  637: 
  638:   return msg_new (msgtype, nmsg, seqnum, len);
  639: }
  640: 
  641: #endif /* SUPPORT_OSPF_API */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>