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

    1: /*
    2:  * Public definitions pertaining to the Forwarding Plane Manager component.
    3:  *
    4:  * Permission is granted to use, copy, modify and/or distribute this
    5:  * software under either one of the licenses below.
    6:  *
    7:  * Note that if you use other files from the Quagga tree directly or
    8:  * indirectly, then the licenses in those files still apply.
    9:  *
   10:  * Please retain both licenses below when modifying this code in the
   11:  * Quagga tree.
   12:  *
   13:  * Copyright (C) 2012 by Open Source Routing.
   14:  * Copyright (C) 2012 by Internet Systems Consortium, Inc. ("ISC")
   15:  */
   16: 
   17: /*
   18:  * License Option 1: GPL
   19:  *
   20:  * This program is free software; you can redistribute it and/or modify it
   21:  * under the terms of the GNU General Public License as published by the Free
   22:  * Software Foundation; either version 2 of the License, or (at your option)
   23:  * any later version.
   24:  *
   25:  * This program is distributed in the hope that it will be useful,but WITHOUT
   26:  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   27:  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   28:  * more details.
   29:  *
   30:  * You should have received a copy of the GNU General Public License along
   31:  * with this program; if not, write to the Free Software Foundation, Inc.,
   32:  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   33:  */
   34: 
   35: /*
   36:  * License Option 2: ISC License
   37:  *
   38:  * Permission to use, copy, modify, and/or distribute this software
   39:  * for any purpose with or without fee is hereby granted, provided
   40:  * that the above copyright notice and this permission notice appear
   41:  * in all copies.
   42:  *
   43:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
   44:  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
   45:  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
   46:  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
   47:  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
   48:  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
   49:  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
   50:  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   51:  */
   52: 
   53: #ifndef _FPM_H
   54: #define _FPM_H
   55: 
   56: /*
   57:  * The Forwarding Plane Manager (FPM) is an optional component that
   58:  * may be used in scenarios where the router has a forwarding path
   59:  * that is distinct from the kernel, commonly a hardware-based fast
   60:  * path. It is responsible for programming forwarding information
   61:  * (such as routes and nexthops) in the fast path.
   62:  *
   63:  * In Quagga, the Routing Information Base is maintained in the
   64:  * 'zebra' infrastructure daemon. Routing protocols communicate their
   65:  * best routes to zebra, and zebra computes the best route across
   66:  * protocols for each prefix. This latter information comprises the
   67:  * bulk of the Forwarding Information Base.
   68:  *
   69:  * This header file defines a point-to-point interface using which
   70:  * zebra can update the FPM about changes in routes. The communication
   71:  * takes place over a stream socket. The FPM listens on a well-known
   72:  * TCP port, and zebra initiates the connection.
   73:  *
   74:  * All messages sent over the connection start with a short FPM
   75:  * header, fpm_msg_hdr_t. In the case of route add/delete messages,
   76:  * the header is followed by a netlink message. Zebra should send a
   77:  * complete copy of the forwarding table(s) to the FPM, including
   78:  * routes that it may have picked up from the kernel.
   79:  *
   80:  * The FPM interface uses replace semantics. That is, if a 'route add'
   81:  * message for a prefix is followed by another 'route add' message, the
   82:  * information in the second message is complete by itself, and replaces
   83:  * the information sent in the first message.
   84:  *
   85:  * If the connection to the FPM goes down for some reason, the client
   86:  * (zebra) should send the FPM a complete copy of the forwarding
   87:  * table(s) when it reconnects.
   88:  */
   89: 
   90: #define FPM_DEFAULT_PORT 2620
   91: 
   92: /*
   93:  * Largest message that can be sent to or received from the FPM.
   94:  */
   95: #define FPM_MAX_MSG_LEN 4096
   96: 
   97: /*
   98:  * Header that precedes each fpm message to/from the FPM.
   99:  */
  100: typedef struct fpm_msg_hdr_t_
  101: {
  102:   /*
  103:    * Protocol version.
  104:    */
  105:   uint8_t version;
  106: 
  107:   /*
  108:    * Type of message, see below.
  109:    */
  110:   uint8_t msg_type;
  111: 
  112:   /*
  113:    * Length of entire message, including the header, in network byte
  114:    * order.
  115:    *
  116:    * Note that msg_len is rounded up to make sure that message is at
  117:    * the desired alignment. This means that some payloads may need
  118:    * padding at the end.
  119:    */
  120:   uint16_t msg_len;
  121: } fpm_msg_hdr_t;
  122: 
  123: /*
  124:  * The current version of the FPM protocol is 1.
  125:  */
  126: #define FPM_PROTO_VERSION 1
  127: 
  128: typedef enum fpm_msg_type_e_ {
  129:   FPM_MSG_TYPE_NONE = 0,
  130: 
  131:   /*
  132:    * Indicates that the payload is a completely formed netlink
  133:    * message.
  134:    */
  135:   FPM_MSG_TYPE_NETLINK = 1,
  136: } fpm_msg_type_e;
  137: 
  138: /*
  139:  * The FPM message header is aligned to the same boundary as netlink
  140:  * messages (4). This means that a netlink message does not need
  141:  * padding when encapsulated in an FPM message.
  142:  */
  143: #define FPM_MSG_ALIGNTO 4
  144: 
  145: /*
  146:  * fpm_msg_align
  147:  *
  148:  * Round up the given length to the desired alignment.
  149:  */
  150: static inline size_t
  151: fpm_msg_align (size_t len)
  152: {
  153:   return (len + FPM_MSG_ALIGNTO - 1) & ~(FPM_MSG_ALIGNTO - 1);
  154: }
  155: 
  156: /*
  157:  * The (rounded up) size of the FPM message header. This ensures that
  158:  * the message payload always starts at an aligned address.
  159:  */
  160: #define FPM_MSG_HDR_LEN (fpm_msg_align (sizeof (fpm_msg_hdr_t)))
  161: 
  162: /*
  163:  * fpm_data_len_to_msg_len
  164:  *
  165:  * The length value that should be placed in the msg_len field of the
  166:  * header for a *payload* of size 'data_len'.
  167:  */
  168: static inline size_t
  169: fpm_data_len_to_msg_len (size_t data_len)
  170: {
  171:   return fpm_msg_align (data_len) + FPM_MSG_HDR_LEN;
  172: }
  173: 
  174: /*
  175:  * fpm_msg_data
  176:  *
  177:  * Pointer to the payload of the given fpm header.
  178:  */
  179: static inline void *
  180: fpm_msg_data (fpm_msg_hdr_t *hdr)
  181: {
  182:   return ((char*) hdr) + FPM_MSG_HDR_LEN;
  183: }
  184: 
  185: /*
  186:  * fpm_msg_len
  187:  */
  188: static inline size_t
  189: fpm_msg_len (const fpm_msg_hdr_t *hdr)
  190: {
  191:   return ntohs (hdr->msg_len);
  192: }
  193: 
  194: /*
  195:  * fpm_msg_data_len
  196:  */
  197: static inline size_t
  198: fpm_msg_data_len (const fpm_msg_hdr_t *hdr)
  199: {
  200:   return (fpm_msg_len (hdr) - FPM_MSG_HDR_LEN);
  201: }
  202: 
  203: /*
  204:  * fpm_msg_next
  205:  *
  206:  * Move to the next message in a buffer.
  207:  */
  208: static inline fpm_msg_hdr_t *
  209: fpm_msg_next (fpm_msg_hdr_t *hdr, size_t *len)
  210: {
  211:   size_t msg_len;
  212: 
  213:   msg_len = fpm_msg_len (hdr);
  214: 
  215:   if (len) {
  216:     if (*len < msg_len)
  217:       {
  218: 	assert(0);
  219: 	return NULL;
  220:       }
  221:     *len -= msg_len;
  222:   }
  223: 
  224:   return (fpm_msg_hdr_t *) (((char*) hdr) + msg_len);
  225: }
  226: 
  227: /*
  228:  * fpm_msg_hdr_ok
  229:  *
  230:  * Returns TRUE if a message header looks well-formed.
  231:  */
  232: static inline int
  233: fpm_msg_hdr_ok (const fpm_msg_hdr_t *hdr)
  234: {
  235:   size_t msg_len;
  236: 
  237:   if (hdr->msg_type == FPM_MSG_TYPE_NONE)
  238:     return 0;
  239: 
  240:   msg_len = fpm_msg_len (hdr);
  241: 
  242:   if (msg_len < FPM_MSG_HDR_LEN || msg_len > FPM_MAX_MSG_LEN)
  243:     return 0;
  244: 
  245:   if (fpm_msg_align (msg_len) != msg_len)
  246:     return 0;
  247: 
  248:   return 1;
  249: }
  250: 
  251: /*
  252:  * fpm_msg_ok
  253:  *
  254:  * Returns TRUE if a message looks well-formed.
  255:  *
  256:  * @param len The length in bytes from 'hdr' to the end of the buffer.
  257:  */
  258: static inline int
  259: fpm_msg_ok (const fpm_msg_hdr_t *hdr, size_t len)
  260: {
  261:   if (len < FPM_MSG_HDR_LEN)
  262:     return 0;
  263: 
  264:   if (!fpm_msg_hdr_ok (hdr))
  265:     return 0;
  266: 
  267:   if (fpm_msg_len (hdr) > len)
  268:     return 0;
  269: 
  270:   return 1;
  271: }
  272: 
  273: #endif /* _FPM_H */

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