Annotation of embedaddon/quagga/fpm/fpm.h, revision 1.1
1.1 ! misho 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>