Annotation of embedaddon/quagga/babeld/message.c, revision 1.1.1.1

1.1       misho       1: /*  
                      2:  *  This file is free software: you may copy, redistribute and/or modify it  
                      3:  *  under the terms of the GNU General Public License as published by the  
                      4:  *  Free Software Foundation, either version 2 of the License, or (at your  
                      5:  *  option) any later version.  
                      6:  *  
                      7:  *  This file is distributed in the hope that it will be useful, but  
                      8:  *  WITHOUT ANY WARRANTY; without even the implied warranty of  
                      9:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  
                     10:  *  General Public License for more details.  
                     11:  *  
                     12:  *  You should have received a copy of the GNU General Public License  
                     13:  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  
                     14:  *  
                     15:  * This file incorporates work covered by the following copyright and  
                     16:  * permission notice:  
                     17:  *  
                     18: 
                     19: Copyright (c) 2007, 2008 by Juliusz Chroboczek
                     20: 
                     21: Permission is hereby granted, free of charge, to any person obtaining a copy
                     22: of this software and associated documentation files (the "Software"), to deal
                     23: in the Software without restriction, including without limitation the rights
                     24: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     25: copies of the Software, and to permit persons to whom the Software is
                     26: furnished to do so, subject to the following conditions:
                     27: 
                     28: The above copyright notice and this permission notice shall be included in
                     29: all copies or substantial portions of the Software.
                     30: 
                     31: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     32: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     33: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
                     34: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     35: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     36: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     37: THE SOFTWARE.
                     38: */
                     39: 
                     40: #include <zebra.h>
                     41: #include "if.h"
                     42: 
                     43: #include "babeld.h"
                     44: #include "util.h"
                     45: #include "net.h"
                     46: #include "babel_interface.h"
                     47: #include "source.h"
                     48: #include "neighbour.h"
                     49: #include "route.h"
                     50: #include "xroute.h"
                     51: #include "resend.h"
                     52: #include "message.h"
                     53: #include "kernel.h"
                     54: 
                     55: unsigned char packet_header[4] = {42, 2};
                     56: 
                     57: int split_horizon = 1;
                     58: 
                     59: unsigned short myseqno = 0;
                     60: struct timeval seqno_time = {0, 0};
                     61: 
                     62: #define UNICAST_BUFSIZE 1024
                     63: int unicast_buffered = 0;
                     64: unsigned char *unicast_buffer = NULL;
                     65: struct neighbour *unicast_neighbour = NULL;
                     66: struct timeval unicast_flush_timeout = {0, 0};
                     67: 
                     68: static const unsigned char v4prefix[16] =
                     69:     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
                     70: 
                     71: /* Parse a network prefix, encoded in the somewhat baroque compressed
                     72:    representation used by Babel.  Return the number of bytes parsed. */
                     73: static int
                     74: network_prefix(int ae, int plen, unsigned int omitted,
                     75:                const unsigned char *p, const unsigned char *dp,
                     76:                unsigned int len, unsigned char *p_r)
                     77: {
                     78:     unsigned pb;
                     79:     unsigned char prefix[16];
                     80:     int ret = -1;
                     81: 
                     82:     if(plen >= 0)
                     83:         pb = (plen + 7) / 8;
                     84:     else if(ae == 1)
                     85:         pb = 4;
                     86:     else
                     87:         pb = 16;
                     88: 
                     89:     if(pb > 16)
                     90:         return -1;
                     91: 
                     92:     memset(prefix, 0, 16);
                     93: 
                     94:     switch(ae) {
                     95:     case 0:
                     96:         ret = 0;
                     97:         break;
                     98:     case 1:
                     99:         if(omitted > 4 || pb > 4 || (pb > omitted && len < pb - omitted))
                    100:             return -1;
                    101:         memcpy(prefix, v4prefix, 12);
                    102:         if(omitted) {
                    103:             if (dp == NULL || !v4mapped(dp)) return -1;
                    104:             memcpy(prefix, dp, 12 + omitted);
                    105:         }
                    106:         if(pb > omitted) memcpy(prefix + 12 + omitted, p, pb - omitted);
                    107:         ret = pb - omitted;
                    108:         break;
                    109:     case 2:
                    110:         if(omitted > 16 || (pb > omitted && len < pb - omitted)) return -1;
                    111:         if(omitted) {
                    112:             if (dp == NULL || v4mapped(dp)) return -1;
                    113:             memcpy(prefix, dp, omitted);
                    114:         }
                    115:         if(pb > omitted) memcpy(prefix + omitted, p, pb - omitted);
                    116:         ret = pb - omitted;
                    117:         break;
                    118:     case 3:
                    119:         if(pb > 8 && len < pb - 8) return -1;
                    120:         prefix[0] = 0xfe;
                    121:         prefix[1] = 0x80;
                    122:         if(pb > 8) memcpy(prefix + 8, p, pb - 8);
                    123:         ret = pb - 8;
                    124:         break;
                    125:     default:
                    126:         return -1;
                    127:     }
                    128: 
                    129:     mask_prefix(p_r, prefix, plen < 0 ? 128 : ae == 1 ? plen + 96 : plen);
                    130:     return ret;
                    131: }
                    132: 
                    133: static void
                    134: parse_route_attributes(const unsigned char *a, int alen,
                    135:                        unsigned char *channels)
                    136: {
                    137:     int type, len, i = 0;
                    138: 
                    139:     while(i < alen) {
                    140:         type = a[i];
                    141:         if(type == 0) {
                    142:             i++;
                    143:             continue;
                    144:         }
                    145: 
                    146:         if(i + 1 > alen) {
                    147:             fprintf(stderr, "Received truncated attributes.\n");
                    148:             return;
                    149:         }
                    150:         len = a[i + 1];
                    151:         if(i + len > alen) {
                    152:             fprintf(stderr, "Received truncated attributes.\n");
                    153:             return;
                    154:         }
                    155: 
                    156:         if(type == 1) {
                    157:             /* Nothing. */
                    158:         } else if(type == 2) {
                    159:             if(len > DIVERSITY_HOPS) {
                    160:                 fprintf(stderr,
                    161:                         "Received overlong channel information (%d > %d).\n",
                    162:                         len, DIVERSITY_HOPS);
                    163:                 len = DIVERSITY_HOPS;
                    164:             }
                    165:             if(memchr(a + i + 2, 0, len) != NULL) {
                    166:                 /* 0 is reserved. */
                    167:                 fprintf(stderr, "Channel information contains 0!");
                    168:                 return;
                    169:             }
                    170:             memset(channels, 0, DIVERSITY_HOPS);
                    171:             memcpy(channels, a + i + 2, len);
                    172:         } else {
                    173:             fprintf(stderr, "Received unknown route attribute %d.\n", type);
                    174:         }
                    175: 
                    176:         i += len + 2;
                    177:     }
                    178: }
                    179: 
                    180: static int
                    181: network_address(int ae, const unsigned char *a, unsigned int len,
                    182:                 unsigned char *a_r)
                    183: {
                    184:     return network_prefix(ae, -1, 0, a, NULL, len, a_r);
                    185: }
                    186: 
                    187: static int
                    188: channels_len(unsigned char *channels)
                    189: {
                    190:     unsigned char *p = memchr(channels, 0, DIVERSITY_HOPS);
                    191:     return p ? (p - channels) : DIVERSITY_HOPS;
                    192: }
                    193: 
                    194: void
                    195: parse_packet(const unsigned char *from, struct interface *ifp,
                    196:              const unsigned char *packet, int packetlen)
                    197: {
                    198:     int i;
                    199:     const unsigned char *message;
                    200:     unsigned char type, len;
                    201:     int bodylen;
                    202:     struct neighbour *neigh;
                    203:     int have_router_id = 0, have_v4_prefix = 0, have_v6_prefix = 0,
                    204:         have_v4_nh = 0, have_v6_nh = 0;
                    205:     unsigned char router_id[8], v4_prefix[16], v6_prefix[16],
                    206:         v4_nh[16], v6_nh[16];
                    207: 
                    208:     if(!linklocal(from)) {
                    209:         zlog_err("Received packet from non-local address %s.",
                    210:                  format_address(from));
                    211:         return;
                    212:     }
                    213: 
                    214:     if(packet[0] != 42) {
                    215:         zlog_err("Received malformed packet on %s from %s.",
                    216:                  ifp->name, format_address(from));
                    217:         return;
                    218:     }
                    219: 
                    220:     if(packet[1] != 2) {
                    221:         zlog_err("Received packet with unknown version %d on %s from %s.",
                    222:                  packet[1], ifp->name, format_address(from));
                    223:         return;
                    224:     }
                    225: 
                    226:     neigh = find_neighbour(from, ifp);
                    227:     if(neigh == NULL) {
                    228:         zlog_err("Couldn't allocate neighbour.");
                    229:         return;
                    230:     }
                    231: 
                    232:     DO_NTOHS(bodylen, packet + 2);
                    233: 
                    234:     if(bodylen + 4 > packetlen) {
                    235:         zlog_err("Received truncated packet (%d + 4 > %d).",
                    236:                  bodylen, packetlen);
                    237:         bodylen = packetlen - 4;
                    238:     }
                    239: 
                    240:     i = 0;
                    241:     while(i < bodylen) {
                    242:         message = packet + 4 + i;
                    243:         type = message[0];
                    244:         if(type == MESSAGE_PAD1) {
                    245:             debugf(BABEL_DEBUG_COMMON,"Received pad1 from %s on %s.",
                    246:                    format_address(from), ifp->name);
                    247:             i++;
                    248:             continue;
                    249:         }
                    250:         if(i + 1 > bodylen) {
                    251:             zlog_err("Received truncated message.");
                    252:             break;
                    253:         }
                    254:         len = message[1];
                    255:         if(i + len > bodylen) {
                    256:             zlog_err("Received truncated message.");
                    257:             break;
                    258:         }
                    259: 
                    260:         if(type == MESSAGE_PADN) {
                    261:             debugf(BABEL_DEBUG_COMMON,"Received pad%d from %s on %s.",
                    262:                    len, format_address(from), ifp->name);
                    263:         } else if(type == MESSAGE_ACK_REQ) {
                    264:             unsigned short nonce, interval;
                    265:             if(len < 6) goto fail;
                    266:             DO_NTOHS(nonce, message + 4);
                    267:             DO_NTOHS(interval, message + 6);
                    268:             debugf(BABEL_DEBUG_COMMON,"Received ack-req (%04X %d) from %s on %s.",
                    269:                    nonce, interval, format_address(from), ifp->name);
                    270:             send_ack(neigh, nonce, interval);
                    271:         } else if(type == MESSAGE_ACK) {
                    272:             debugf(BABEL_DEBUG_COMMON,"Received ack from %s on %s.",
                    273:                    format_address(from), ifp->name);
                    274:             /* Nothing right now */
                    275:         } else if(type == MESSAGE_HELLO) {
                    276:             unsigned short seqno, interval;
                    277:             int changed;
                    278:             if(len < 6) goto fail;
                    279:             DO_NTOHS(seqno, message + 4);
                    280:             DO_NTOHS(interval, message + 6);
                    281:             debugf(BABEL_DEBUG_COMMON,"Received hello %d (%d) from %s on %s.",
                    282:                    seqno, interval,
                    283:                    format_address(from), ifp->name);
                    284:             changed = update_neighbour(neigh, seqno, interval);
                    285:             update_neighbour_metric(neigh, changed);
                    286:             if(interval > 0)
                    287:                 schedule_neighbours_check(interval * 10, 0);
                    288:         } else if(type == MESSAGE_IHU) {
                    289:             unsigned short txcost, interval;
                    290:             unsigned char address[16];
                    291:             int rc;
                    292:             if(len < 6) goto fail;
                    293:             DO_NTOHS(txcost, message + 4);
                    294:             DO_NTOHS(interval, message + 6);
                    295:             rc = network_address(message[2], message + 8, len - 6, address);
                    296:             if(rc < 0) goto fail;
                    297:             debugf(BABEL_DEBUG_COMMON,"Received ihu %d (%d) from %s on %s for %s.",
                    298:                    txcost, interval,
                    299:                    format_address(from), ifp->name,
                    300:                    format_address(address));
                    301:             if(message[2] == 0 || is_interface_ll_address(ifp, address)) {
                    302:                 int changed = txcost != neigh->txcost;
                    303:                 neigh->txcost = txcost;
                    304:                 neigh->ihu_time = babel_now;
                    305:                 neigh->ihu_interval = interval;
                    306:                 update_neighbour_metric(neigh, changed);
                    307:                 if(interval > 0)
                    308:                     schedule_neighbours_check(interval * 10 * 3, 0);
                    309:             }
                    310:         } else if(type == MESSAGE_ROUTER_ID) {
                    311:             if(len < 10) {
                    312:                 have_router_id = 0;
                    313:                 goto fail;
                    314:             }
                    315:             memcpy(router_id, message + 4, 8);
                    316:             have_router_id = 1;
                    317:             debugf(BABEL_DEBUG_COMMON,"Received router-id %s from %s on %s.",
                    318:                    format_eui64(router_id), format_address(from), ifp->name);
                    319:         } else if(type == MESSAGE_NH) {
                    320:             unsigned char nh[16];
                    321:             int rc;
                    322:             if(len < 2) {
                    323:                 have_v4_nh = 0;
                    324:                 have_v6_nh = 0;
                    325:                 goto fail;
                    326:             }
                    327:             rc = network_address(message[2], message + 4, len - 2,
                    328:                                  nh);
                    329:             if(rc < 0) {
                    330:                 have_v4_nh = 0;
                    331:                 have_v6_nh = 0;
                    332:                 goto fail;
                    333:             }
                    334:             debugf(BABEL_DEBUG_COMMON,"Received nh %s (%d) from %s on %s.",
                    335:                    format_address(nh), message[2],
                    336:                    format_address(from), ifp->name);
                    337:             if(message[2] == 1) {
                    338:                 memcpy(v4_nh, nh, 16);
                    339:                 have_v4_nh = 1;
                    340:             } else {
                    341:                 memcpy(v6_nh, nh, 16);
                    342:                 have_v6_nh = 1;
                    343:             }
                    344:         } else if(type == MESSAGE_UPDATE) {
                    345:             unsigned char prefix[16], *nh;
                    346:             unsigned char plen;
                    347:             unsigned char channels[DIVERSITY_HOPS];
                    348:             unsigned short interval, seqno, metric;
                    349:             int rc, parsed_len;
                    350:             if(len < 10) {
                    351:                 if(len < 2 || message[3] & 0x80)
                    352:                     have_v4_prefix = have_v6_prefix = 0;
                    353:                 goto fail;
                    354:             }
                    355:             DO_NTOHS(interval, message + 6);
                    356:             DO_NTOHS(seqno, message + 8);
                    357:             DO_NTOHS(metric, message + 10);
                    358:             if(message[5] == 0 ||
                    359:                (message[3] == 1 ? have_v4_prefix : have_v6_prefix))
                    360:                 rc = network_prefix(message[2], message[4], message[5],
                    361:                                     message + 12,
                    362:                                     message[2] == 1 ? v4_prefix : v6_prefix,
                    363:                                     len - 10, prefix);
                    364:             else
                    365:                 rc = -1;
                    366:             if(rc < 0) {
                    367:                 if(message[3] & 0x80)
                    368:                     have_v4_prefix = have_v6_prefix = 0;
                    369:                 goto fail;
                    370:             }
                    371:             parsed_len = 10 + rc;
                    372: 
                    373:             plen = message[4] + (message[2] == 1 ? 96 : 0);
                    374: 
                    375:             if(message[3] & 0x80) {
                    376:                 if(message[2] == 1) {
                    377:                     memcpy(v4_prefix, prefix, 16);
                    378:                     have_v4_prefix = 1;
                    379:                 } else {
                    380:                     memcpy(v6_prefix, prefix, 16);
                    381:                     have_v6_prefix = 1;
                    382:                 }
                    383:             }
                    384:             if(message[3] & 0x40) {
                    385:                 if(message[2] == 1) {
                    386:                     memset(router_id, 0, 4);
                    387:                     memcpy(router_id + 4, prefix + 12, 4);
                    388:                 } else {
                    389:                     memcpy(router_id, prefix + 8, 8);
                    390:                 }
                    391:                 have_router_id = 1;
                    392:             }
                    393:             if(!have_router_id && message[2] != 0) {
                    394:                 zlog_err("Received prefix with no router id.");
                    395:                 goto fail;
                    396:             }
                    397:             debugf(BABEL_DEBUG_COMMON,"Received update%s%s for %s from %s on %s.",
                    398:                    (message[3] & 0x80) ? "/prefix" : "",
                    399:                    (message[3] & 0x40) ? "/id" : "",
                    400:                    format_prefix(prefix, plen),
                    401:                    format_address(from), ifp->name);
                    402: 
                    403:             if(message[2] == 0) {
                    404:                 if(metric < 0xFFFF) {
                    405:                     zlog_err("Received wildcard update with finite metric.");
                    406:                     goto done;
                    407:                 }
                    408:                 retract_neighbour_routes(neigh);
                    409:                 goto done;
                    410:             } else if(message[2] == 1) {
                    411:                 if(!have_v4_nh)
                    412:                     goto fail;
                    413:                 nh = v4_nh;
                    414:             } else if(have_v6_nh) {
                    415:                 nh = v6_nh;
                    416:             } else {
                    417:                 nh = neigh->address;
                    418:             }
                    419: 
                    420:             if(message[2] == 1) {
                    421:                 if(!babel_get_if_nfo(ifp)->ipv4)
                    422:                     goto done;
                    423:             }
                    424: 
                    425:             if((ifp->flags & BABEL_IF_FARAWAY)) {
                    426:                 channels[0] = 0;
                    427:             } else {
                    428:                 /* This will be overwritten by parse_route_attributes below. */
                    429:                 if(metric < 256) {
                    430:                     /* Assume non-interfering (wired) link. */
                    431:                     channels[0] = 0;
                    432:                 } else {
                    433:                     /* Assume interfering. */
                    434:                     channels[0] = BABEL_IF_CHANNEL_INTERFERING;
                    435:                     channels[1] = 0;
                    436:                 }
                    437: 
                    438:                 if(parsed_len < len)
                    439:                     parse_route_attributes(message + 2 + parsed_len,
                    440:                                            len - parsed_len, channels);
                    441:             }
                    442: 
                    443:             update_route(router_id, prefix, plen, seqno, metric, interval,
                    444:                          neigh, nh,
                    445:                          channels, channels_len(channels));
                    446:         } else if(type == MESSAGE_REQUEST) {
                    447:             unsigned char prefix[16], plen;
                    448:             int rc;
                    449:             if(len < 2) goto fail;
                    450:             rc = network_prefix(message[2], message[3], 0,
                    451:                                 message + 4, NULL, len - 2, prefix);
                    452:             if(rc < 0) goto fail;
                    453:             plen = message[3] + (message[2] == 1 ? 96 : 0);
                    454:             debugf(BABEL_DEBUG_COMMON,"Received request for %s from %s on %s.",
                    455:                    message[2] == 0 ? "any" : format_prefix(prefix, plen),
                    456:                    format_address(from), ifp->name);
                    457:             if(message[2] == 0) {
                    458:                 struct babel_interface *babel_ifp =babel_get_if_nfo(neigh->ifp);
                    459:                 /* If a neighbour is requesting a full route dump from us,
                    460:                    we might as well send it an IHU. */
                    461:                 send_ihu(neigh, NULL);
                    462:                 /* Since nodes send wildcard requests on boot, booting
                    463:                    a large number of nodes at the same time may cause an
                    464:                    update storm.  Ignore a wildcard request that happens
                    465:                    shortly after we sent a full update. */
                    466:                 if(babel_ifp->last_update_time <
                    467:                    (time_t)(babel_now.tv_sec -
                    468:                             MAX(babel_ifp->hello_interval / 100, 1)))
                    469:                     send_update(neigh->ifp, 0, NULL, 0);
                    470:             } else {
                    471:                 send_update(neigh->ifp, 0, prefix, plen);
                    472:             }
                    473:         } else if(type == MESSAGE_MH_REQUEST) {
                    474:             unsigned char prefix[16], plen;
                    475:             unsigned short seqno;
                    476:             int rc;
                    477:             if(len < 14) goto fail;
                    478:             DO_NTOHS(seqno, message + 4);
                    479:             rc = network_prefix(message[2], message[3], 0,
                    480:                                 message + 16, NULL, len - 14, prefix);
                    481:             if(rc < 0) goto fail;
                    482:             plen = message[3] + (message[2] == 1 ? 96 : 0);
                    483:             debugf(BABEL_DEBUG_COMMON,"Received request (%d) for %s from %s on %s (%s, %d).",
                    484:                    message[6],
                    485:                    format_prefix(prefix, plen),
                    486:                    format_address(from), ifp->name,
                    487:                    format_eui64(message + 8), seqno);
                    488:             handle_request(neigh, prefix, plen, message[6],
                    489:                            seqno, message + 8);
                    490:         } else {
                    491:             debugf(BABEL_DEBUG_COMMON,"Received unknown packet type %d from %s on %s.",
                    492:                    type, format_address(from), ifp->name);
                    493:         }
                    494:     done:
                    495:         i += len + 2;
                    496:         continue;
                    497: 
                    498:     fail:
                    499:         zlog_err("Couldn't parse packet (%d, %d) from %s on %s.",
                    500:                  message[0], message[1], format_address(from), ifp->name);
                    501:         goto done;
                    502:     }
                    503:     return;
                    504: }
                    505: 
                    506: /* Under normal circumstances, there are enough moderation mechanisms
                    507:    elsewhere in the protocol to make sure that this last-ditch check
                    508:    should never trigger.  But I'm superstitious. */
                    509: 
                    510: static int
                    511: check_bucket(struct interface *ifp)
                    512: {
                    513:     babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
                    514:     if(babel_ifp->bucket <= 0) {
                    515:         int seconds = babel_now.tv_sec - babel_ifp->bucket_time;
                    516:         if(seconds > 0) {
                    517:             babel_ifp->bucket = MIN(BUCKET_TOKENS_MAX,
                    518:                               seconds * BUCKET_TOKENS_PER_SEC);
                    519:         }
                    520:         /* Reset bucket time unconditionally, in case clock is stepped. */
                    521:         babel_ifp->bucket_time = babel_now.tv_sec;
                    522:     }
                    523: 
                    524:     if(babel_ifp->bucket > 0) {
                    525:         babel_ifp->bucket--;
                    526:         return 1;
                    527:     } else {
                    528:         return 0;
                    529:     }
                    530: }
                    531: 
                    532: void
                    533: flushbuf(struct interface *ifp)
                    534: {
                    535:     int rc;
                    536:     struct sockaddr_in6 sin6;
                    537:     babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
                    538: 
                    539:     assert(babel_ifp->buffered <= babel_ifp->bufsize);
                    540: 
                    541:     flushupdates(ifp);
                    542: 
                    543:     if(babel_ifp->buffered > 0) {
                    544:         debugf(BABEL_DEBUG_COMMON,"  (flushing %d buffered bytes on %s)",
                    545:                babel_ifp->buffered, ifp->name);
                    546:         if(check_bucket(ifp)) {
                    547:             memset(&sin6, 0, sizeof(sin6));
                    548:             sin6.sin6_family = AF_INET6;
                    549:             memcpy(&sin6.sin6_addr, protocol_group, 16);
                    550:             sin6.sin6_port = htons(protocol_port);
                    551:             sin6.sin6_scope_id = ifp->ifindex;
                    552:             DO_HTONS(packet_header + 2, babel_ifp->buffered);
                    553:             rc = babel_send(protocol_socket,
                    554:                             packet_header, sizeof(packet_header),
                    555:                             babel_ifp->sendbuf, babel_ifp->buffered,
                    556:                             (struct sockaddr*)&sin6, sizeof(sin6));
                    557:             if(rc < 0)
                    558:                 zlog_err("send: %s", safe_strerror(errno));
                    559:         } else {
                    560:             zlog_err("Warning: bucket full, dropping packet to %s.",
                    561:                      ifp->name);
                    562:         }
                    563:     }
                    564:     VALGRIND_MAKE_MEM_UNDEFINED(babel_ifp->sendbuf, babel_ifp->bufsize);
                    565:     babel_ifp->buffered = 0;
                    566:     babel_ifp->have_buffered_hello = 0;
                    567:     babel_ifp->have_buffered_id = 0;
                    568:     babel_ifp->have_buffered_nh = 0;
                    569:     babel_ifp->have_buffered_prefix = 0;
                    570:     babel_ifp->flush_timeout.tv_sec = 0;
                    571:     babel_ifp->flush_timeout.tv_usec = 0;
                    572: }
                    573: 
                    574: static void
                    575: schedule_flush(struct interface *ifp)
                    576: {
                    577:     babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
                    578:     unsigned msecs = jitter(babel_ifp, 0);
                    579:     if(babel_ifp->flush_timeout.tv_sec != 0 &&
                    580:        timeval_minus_msec(&babel_ifp->flush_timeout, &babel_now) < msecs)
                    581:         return;
                    582:     set_timeout(&babel_ifp->flush_timeout, msecs);
                    583: }
                    584: 
                    585: static void
                    586: schedule_flush_now(struct interface *ifp)
                    587: {
                    588:     babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
                    589:     /* Almost now */
                    590:     unsigned msecs = roughly(10);
                    591:     if(babel_ifp->flush_timeout.tv_sec != 0 &&
                    592:        timeval_minus_msec(&babel_ifp->flush_timeout, &babel_now) < msecs)
                    593:         return;
                    594:     set_timeout(&babel_ifp->flush_timeout, msecs);
                    595: }
                    596: 
                    597: static void
                    598: schedule_unicast_flush(unsigned msecs)
                    599: {
                    600:     if(!unicast_neighbour)
                    601:         return;
                    602:     if(unicast_flush_timeout.tv_sec != 0 &&
                    603:        timeval_minus_msec(&unicast_flush_timeout, &babel_now) < msecs)
                    604:         return;
                    605:     unicast_flush_timeout.tv_usec = (babel_now.tv_usec + msecs * 1000) %1000000;
                    606:     unicast_flush_timeout.tv_sec =
                    607:         babel_now.tv_sec + (babel_now.tv_usec / 1000 + msecs) / 1000;
                    608: }
                    609: 
                    610: static void
                    611: ensure_space(struct interface *ifp, int space)
                    612: {
                    613:     babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
                    614:     if(babel_ifp->bufsize - babel_ifp->buffered < space)
                    615:         flushbuf(ifp);
                    616: }
                    617: 
                    618: static void
                    619: start_message(struct interface *ifp, int type, int len)
                    620: {
                    621:   babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
                    622:     if(babel_ifp->bufsize - babel_ifp->buffered < len + 2)
                    623:         flushbuf(ifp);
                    624:     babel_ifp->sendbuf[babel_ifp->buffered++] = type;
                    625:     babel_ifp->sendbuf[babel_ifp->buffered++] = len;
                    626: }
                    627: 
                    628: static void
                    629: end_message(struct interface *ifp, int type, int bytes)
                    630: {
                    631:     babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
                    632:     assert(babel_ifp->buffered >= bytes + 2 &&
                    633:            babel_ifp->sendbuf[babel_ifp->buffered - bytes - 2] == type &&
                    634:            babel_ifp->sendbuf[babel_ifp->buffered - bytes - 1] == bytes);
                    635:     schedule_flush(ifp);
                    636: }
                    637: 
                    638: static void
                    639: accumulate_byte(struct interface *ifp, unsigned char value)
                    640: {
                    641:     babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
                    642:     babel_ifp->sendbuf[babel_ifp->buffered++] = value;
                    643: }
                    644: 
                    645: static void
                    646: accumulate_short(struct interface *ifp, unsigned short value)
                    647: {
                    648:     babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
                    649:     DO_HTONS(babel_ifp->sendbuf + babel_ifp->buffered, value);
                    650:     babel_ifp->buffered += 2;
                    651: }
                    652: 
                    653: static void
                    654: accumulate_bytes(struct interface *ifp,
                    655:                  const unsigned char *value, unsigned len)
                    656: {
                    657:     babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
                    658:     memcpy(babel_ifp->sendbuf + babel_ifp->buffered, value, len);
                    659:     babel_ifp->buffered += len;
                    660: }
                    661: 
                    662: static int
                    663: start_unicast_message(struct neighbour *neigh, int type, int len)
                    664: {
                    665:     if(unicast_neighbour) {
                    666:         if(neigh != unicast_neighbour ||
                    667:            unicast_buffered + len + 2 >=
                    668:            MIN(UNICAST_BUFSIZE, babel_get_if_nfo(neigh->ifp)->bufsize))
                    669:             flush_unicast(0);
                    670:     }
                    671:     if(!unicast_buffer)
                    672:         unicast_buffer = malloc(UNICAST_BUFSIZE);
                    673:     if(!unicast_buffer) {
                    674:         zlog_err("malloc(unicast_buffer): %s", safe_strerror(errno));
                    675:         return -1;
                    676:     }
                    677: 
                    678:     unicast_neighbour = neigh;
                    679: 
                    680:     unicast_buffer[unicast_buffered++] = type;
                    681:     unicast_buffer[unicast_buffered++] = len;
                    682:     return 1;
                    683: }
                    684: 
                    685: static void
                    686: end_unicast_message(struct neighbour *neigh, int type, int bytes)
                    687: {
                    688:     assert(unicast_neighbour == neigh && unicast_buffered >= bytes + 2 &&
                    689:            unicast_buffer[unicast_buffered - bytes - 2] == type &&
                    690:            unicast_buffer[unicast_buffered - bytes - 1] == bytes);
                    691:     schedule_unicast_flush(jitter(babel_get_if_nfo(neigh->ifp), 0));
                    692: }
                    693: 
                    694: static void
                    695: accumulate_unicast_byte(struct neighbour *neigh, unsigned char value)
                    696: {
                    697:     unicast_buffer[unicast_buffered++] = value;
                    698: }
                    699: 
                    700: static void
                    701: accumulate_unicast_short(struct neighbour *neigh, unsigned short value)
                    702: {
                    703:     DO_HTONS(unicast_buffer + unicast_buffered, value);
                    704:     unicast_buffered += 2;
                    705: }
                    706: 
                    707: static void
                    708: accumulate_unicast_bytes(struct neighbour *neigh,
                    709:                          const unsigned char *value, unsigned len)
                    710: {
                    711:     memcpy(unicast_buffer + unicast_buffered, value, len);
                    712:     unicast_buffered += len;
                    713: }
                    714: 
                    715: void
                    716: send_ack(struct neighbour *neigh, unsigned short nonce, unsigned short interval)
                    717: {
                    718:     int rc;
                    719:     debugf(BABEL_DEBUG_COMMON,"Sending ack (%04x) to %s on %s.",
                    720:            nonce, format_address(neigh->address), neigh->ifp->name);
                    721:     rc = start_unicast_message(neigh, MESSAGE_ACK, 2); if(rc < 0) return;
                    722:     accumulate_unicast_short(neigh, nonce);
                    723:     end_unicast_message(neigh, MESSAGE_ACK, 2);
                    724:     /* Roughly yields a value no larger than 3/2, so this meets the deadline */
                    725:     schedule_unicast_flush(roughly(interval * 6));
                    726: }
                    727: 
                    728: void
                    729: send_hello_noupdate(struct interface *ifp, unsigned interval)
                    730: {
                    731:     babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
                    732:     /* This avoids sending multiple hellos in a single packet, which breaks
                    733:        link quality estimation. */
                    734:     if(babel_ifp->have_buffered_hello)
                    735:         flushbuf(ifp);
                    736: 
                    737:     babel_ifp->hello_seqno = seqno_plus(babel_ifp->hello_seqno, 1);
                    738:     set_timeout(&babel_ifp->hello_timeout, babel_ifp->hello_interval);
                    739: 
                    740:     if(!if_up(ifp))
                    741:         return;
                    742: 
                    743:     debugf(BABEL_DEBUG_COMMON,"Sending hello %d (%d) to %s.",
                    744:            babel_ifp->hello_seqno, interval, ifp->name);
                    745: 
                    746:     start_message(ifp, MESSAGE_HELLO, 6);
                    747:     accumulate_short(ifp, 0);
                    748:     accumulate_short(ifp, babel_ifp->hello_seqno);
                    749:     accumulate_short(ifp, interval > 0xFFFF ? 0xFFFF : interval);
                    750:     end_message(ifp, MESSAGE_HELLO, 6);
                    751:     babel_ifp->have_buffered_hello = 1;
                    752: }
                    753: 
                    754: void
                    755: send_hello(struct interface *ifp)
                    756: {
                    757:     babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
                    758:     send_hello_noupdate(ifp, (babel_ifp->hello_interval + 9) / 10);
                    759:     /* Send full IHU every 3 hellos, and marginal IHU each time */
                    760:     if(babel_ifp->hello_seqno % 3 == 0)
                    761:         send_ihu(NULL, ifp);
                    762:     else
                    763:         send_marginal_ihu(ifp);
                    764: }
                    765: 
                    766: void
                    767: flush_unicast(int dofree)
                    768: {
                    769:     struct sockaddr_in6 sin6;
                    770:     int rc;
                    771: 
                    772:     if(unicast_buffered == 0)
                    773:         goto done;
                    774: 
                    775:     if(!if_up(unicast_neighbour->ifp))
                    776:         goto done;
                    777: 
                    778:     /* Preserve ordering of messages */
                    779:     flushbuf(unicast_neighbour->ifp);
                    780: 
                    781:     if(check_bucket(unicast_neighbour->ifp)) {
                    782:         memset(&sin6, 0, sizeof(sin6));
                    783:         sin6.sin6_family = AF_INET6;
                    784:         memcpy(&sin6.sin6_addr, unicast_neighbour->address, 16);
                    785:         sin6.sin6_port = htons(protocol_port);
                    786:         sin6.sin6_scope_id = unicast_neighbour->ifp->ifindex;
                    787:         DO_HTONS(packet_header + 2, unicast_buffered);
                    788:         rc = babel_send(protocol_socket,
                    789:                         packet_header, sizeof(packet_header),
                    790:                         unicast_buffer, unicast_buffered,
                    791:                         (struct sockaddr*)&sin6, sizeof(sin6));
                    792:         if(rc < 0)
                    793:             zlog_err("send(unicast): %s", safe_strerror(errno));
                    794:     } else {
                    795:         zlog_err("Warning: bucket full, dropping unicast packet to %s if %s.",
                    796:                  format_address(unicast_neighbour->address),
                    797:                  unicast_neighbour->ifp->name);
                    798:     }
                    799: 
                    800:  done:
                    801:     VALGRIND_MAKE_MEM_UNDEFINED(unicast_buffer, UNICAST_BUFSIZE);
                    802:     unicast_buffered = 0;
                    803:     if(dofree && unicast_buffer) {
                    804:         free(unicast_buffer);
                    805:         unicast_buffer = NULL;
                    806:     }
                    807:     unicast_neighbour = NULL;
                    808:     unicast_flush_timeout.tv_sec = 0;
                    809:     unicast_flush_timeout.tv_usec = 0;
                    810: }
                    811: 
                    812: static void
                    813: really_send_update(struct interface *ifp,
                    814:                    const unsigned char *id,
                    815:                    const unsigned char *prefix, unsigned char plen,
                    816:                    unsigned short seqno, unsigned short metric,
                    817:                    unsigned char *channels, int channels_len)
                    818: {
                    819:     babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
                    820:     int add_metric, v4, real_plen, omit = 0;
                    821:     const unsigned char *real_prefix;
                    822:     unsigned short flags = 0;
                    823:     int channels_size;
                    824: 
                    825:     if(diversity_kind != DIVERSITY_CHANNEL)
                    826:         channels_len = -1;
                    827: 
                    828:     channels_size = channels_len >= 0 ? channels_len + 2 : 0;
                    829: 
                    830:     if(!if_up(ifp))
                    831:         return;
                    832: 
                    833:     add_metric = output_filter(id, prefix, plen, ifp->ifindex);
                    834:     if(add_metric >= INFINITY)
                    835:         return;
                    836: 
                    837:     metric = MIN(metric + add_metric, INFINITY);
                    838:     /* Worst case */
                    839:     ensure_space(ifp, 20 + 12 + 28);
                    840: 
                    841:     v4 = plen >= 96 && v4mapped(prefix);
                    842: 
                    843:     if(v4) {
                    844:         if(!babel_ifp->ipv4)
                    845:             return;
                    846:         if(!babel_ifp->have_buffered_nh ||
                    847:            memcmp(babel_ifp->buffered_nh, babel_ifp->ipv4, 4) != 0) {
                    848:             start_message(ifp, MESSAGE_NH, 6);
                    849:             accumulate_byte(ifp, 1);
                    850:             accumulate_byte(ifp, 0);
                    851:             accumulate_bytes(ifp, babel_ifp->ipv4, 4);
                    852:             end_message(ifp, MESSAGE_NH, 6);
                    853:             memcpy(babel_ifp->buffered_nh, babel_ifp->ipv4, 4);
                    854:             babel_ifp->have_buffered_nh = 1;
                    855:         }
                    856: 
                    857:         real_prefix = prefix + 12;
                    858:         real_plen = plen - 96;
                    859:     } else {
                    860:         if(babel_ifp->have_buffered_prefix) {
                    861:             while(omit < plen / 8 &&
                    862:                   babel_ifp->buffered_prefix[omit] == prefix[omit])
                    863:                 omit++;
                    864:         }
                    865:         if(!babel_ifp->have_buffered_prefix || plen >= 48)
                    866:             flags |= 0x80;
                    867:         real_prefix = prefix;
                    868:         real_plen = plen;
                    869:     }
                    870: 
                    871:     if(!babel_ifp->have_buffered_id
                    872:        || memcmp(id, babel_ifp->buffered_id, 8) != 0) {
                    873:         if(real_plen == 128 && memcmp(real_prefix + 8, id, 8) == 0) {
                    874:             flags |= 0x40;
                    875:         } else {
                    876:             start_message(ifp, MESSAGE_ROUTER_ID, 10);
                    877:             accumulate_short(ifp, 0);
                    878:             accumulate_bytes(ifp, id, 8);
                    879:             end_message(ifp, MESSAGE_ROUTER_ID, 10);
                    880:         }
                    881:         memcpy(babel_ifp->buffered_id, id, 16);
                    882:         babel_ifp->have_buffered_id = 1;
                    883:     }
                    884: 
                    885:     start_message(ifp, MESSAGE_UPDATE, 10 + (real_plen + 7) / 8 - omit +
                    886:                   channels_size);
                    887:     accumulate_byte(ifp, v4 ? 1 : 2);
                    888:     accumulate_byte(ifp, flags);
                    889:     accumulate_byte(ifp, real_plen);
                    890:     accumulate_byte(ifp, omit);
                    891:     accumulate_short(ifp, (babel_ifp->update_interval + 5) / 10);
                    892:     accumulate_short(ifp, seqno);
                    893:     accumulate_short(ifp, metric);
                    894:     accumulate_bytes(ifp, real_prefix + omit, (real_plen + 7) / 8 - omit);
                    895:     /* Note that an empty channels TLV is different from no such TLV. */
                    896:     if(channels_len >= 0) {
                    897:         accumulate_byte(ifp, 2);
                    898:         accumulate_byte(ifp, channels_len);
                    899:         accumulate_bytes(ifp, channels, channels_len);
                    900:     }
                    901:     end_message(ifp, MESSAGE_UPDATE, 10 + (real_plen + 7) / 8 - omit +
                    902:                 channels_size);
                    903: 
                    904:     if(flags & 0x80) {
                    905:         memcpy(babel_ifp->buffered_prefix, prefix, 16);
                    906:         babel_ifp->have_buffered_prefix = 1;
                    907:     }
                    908: }
                    909: 
                    910: static int
                    911: compare_buffered_updates(const void *av, const void *bv)
                    912: {
                    913:     const struct buffered_update *a = av, *b = bv;
                    914:     int rc, v4a, v4b, ma, mb;
                    915: 
                    916:     rc = memcmp(a->id, b->id, 8);
                    917:     if(rc != 0)
                    918:         return rc;
                    919: 
                    920:     v4a = (a->plen >= 96 && v4mapped(a->prefix));
                    921:     v4b = (b->plen >= 96 && v4mapped(b->prefix));
                    922: 
                    923:     if(v4a > v4b)
                    924:         return 1;
                    925:     else if(v4a < v4b)
                    926:         return -1;
                    927: 
                    928:     ma = (!v4a && a->plen == 128 && memcmp(a->prefix + 8, a->id, 8) == 0);
                    929:     mb = (!v4b && b->plen == 128 && memcmp(b->prefix + 8, b->id, 8) == 0);
                    930: 
                    931:     if(ma > mb)
                    932:         return -1;
                    933:     else if(mb > ma)
                    934:         return 1;
                    935: 
                    936:     if(a->plen < b->plen)
                    937:         return 1;
                    938:     else if(a->plen > b->plen)
                    939:         return -1;
                    940: 
                    941:     return memcmp(a->prefix, b->prefix, 16);
                    942: }
                    943: 
                    944: void
                    945: flushupdates(struct interface *ifp)
                    946: {
                    947:     babel_interface_nfo *babel_ifp = NULL;
                    948:     struct xroute *xroute;
                    949:     struct babel_route *route;
                    950:     const unsigned char *last_prefix = NULL;
                    951:     unsigned char last_plen = 0xFF;
                    952:     int i;
                    953: 
                    954:     if(ifp == NULL) {
                    955:       struct interface *ifp_aux;
                    956:       struct listnode *linklist_node = NULL;
                    957:         FOR_ALL_INTERFACES(ifp_aux, linklist_node)
                    958:             flushupdates(ifp_aux);
                    959:         return;
                    960:     }
                    961: 
                    962:     babel_ifp = babel_get_if_nfo(ifp);
                    963:     if(babel_ifp->num_buffered_updates > 0) {
                    964:         struct buffered_update *b = babel_ifp->buffered_updates;
                    965:         int n = babel_ifp->num_buffered_updates;
                    966: 
                    967:         babel_ifp->buffered_updates = NULL;
                    968:         babel_ifp->update_bufsize = 0;
                    969:         babel_ifp->num_buffered_updates = 0;
                    970: 
                    971:         if(!if_up(ifp))
                    972:             goto done;
                    973: 
                    974:         debugf(BABEL_DEBUG_COMMON,"  (flushing %d buffered updates on %s (%d))",
                    975:                n, ifp->name, ifp->ifindex);
                    976: 
                    977:         /* In order to send fewer update messages, we want to send updates
                    978:            with the same router-id together, with IPv6 going out before IPv4. */
                    979: 
                    980:         for(i = 0; i < n; i++) {
                    981:             route = find_installed_route(b[i].prefix, b[i].plen);
                    982:             if(route)
                    983:                 memcpy(b[i].id, route->src->id, 8);
                    984:             else
                    985:                 memcpy(b[i].id, myid, 8);
                    986:         }
                    987: 
                    988:         qsort(b, n, sizeof(struct buffered_update), compare_buffered_updates);
                    989: 
                    990:         for(i = 0; i < n; i++) {
                    991:             /* The same update may be scheduled multiple times before it is
                    992:                sent out.  Since our buffer is now sorted, it is enough to
                    993:                compare with the previous update. */
                    994: 
                    995:             if(last_prefix) {
                    996:                 if(b[i].plen == last_plen &&
                    997:                    memcmp(b[i].prefix, last_prefix, 16) == 0)
                    998:                     continue;
                    999:             }
                   1000: 
                   1001:             xroute = find_xroute(b[i].prefix, b[i].plen);
                   1002:             route = find_installed_route(b[i].prefix, b[i].plen);
                   1003: 
                   1004:             if(xroute && (!route || xroute->metric <= kernel_metric)) {
                   1005:                 really_send_update(ifp, myid,
                   1006:                                    xroute->prefix, xroute->plen,
                   1007:                                    myseqno, xroute->metric,
                   1008:                                    NULL, 0);
                   1009:                 last_prefix = xroute->prefix;
                   1010:                 last_plen = xroute->plen;
                   1011:             } else if(route) {
                   1012:                 unsigned char channels[DIVERSITY_HOPS];
                   1013:                 int chlen;
                   1014:                 struct interface *route_ifp = route->neigh->ifp;
                   1015:                 struct babel_interface *babel_route_ifp = NULL;
                   1016:                 unsigned short metric;
                   1017:                 unsigned short seqno;
                   1018: 
                   1019:                 seqno = route->seqno;
                   1020:                 metric =
                   1021:                     route_interferes(route, ifp) ?
                   1022:                     route_metric(route) :
                   1023:                     route_metric_noninterfering(route);
                   1024: 
                   1025:                 if(metric < INFINITY)
                   1026:                     satisfy_request(route->src->prefix, route->src->plen,
                   1027:                                     seqno, route->src->id, ifp);
                   1028:                 if((babel_ifp->flags & BABEL_IF_SPLIT_HORIZON) &&
                   1029:                    route->neigh->ifp == ifp)
                   1030:                     continue;
                   1031: 
                   1032:                 babel_route_ifp = babel_get_if_nfo(route_ifp);
                   1033:                 if(babel_route_ifp->channel ==BABEL_IF_CHANNEL_NONINTERFERING) {
                   1034:                     memcpy(channels, route->channels, DIVERSITY_HOPS);
                   1035:                 } else {
                   1036:                     if(babel_route_ifp->channel == BABEL_IF_CHANNEL_UNKNOWN)
                   1037:                         channels[0] = BABEL_IF_CHANNEL_INTERFERING;
                   1038:                     else {
                   1039:                         assert(babel_route_ifp->channel > 0 &&
                   1040:                                babel_route_ifp->channel <= 255);
                   1041:                         channels[0] = babel_route_ifp->channel;
                   1042:                     }
                   1043:                     memcpy(channels + 1, route->channels, DIVERSITY_HOPS - 1);
                   1044:                 }
                   1045: 
                   1046:                 chlen = channels_len(channels);
                   1047:                 really_send_update(ifp, route->src->id,
                   1048:                                    route->src->prefix,
                   1049:                                    route->src->plen,
                   1050:                                    seqno, metric,
                   1051:                                    channels, chlen);
                   1052:                 update_source(route->src, seqno, metric);
                   1053:                 last_prefix = route->src->prefix;
                   1054:                 last_plen = route->src->plen;
                   1055:             } else {
                   1056:             /* There's no route for this prefix.  This can happen shortly
                   1057:                after an xroute has been retracted, so send a retraction. */
                   1058:                 really_send_update(ifp, myid, b[i].prefix, b[i].plen,
                   1059:                                    myseqno, INFINITY, NULL, -1);
                   1060:             }
                   1061:         }
                   1062:         schedule_flush_now(ifp);
                   1063:     done:
                   1064:         free(b);
                   1065:     }
                   1066:     babel_ifp->update_flush_timeout.tv_sec = 0;
                   1067:     babel_ifp->update_flush_timeout.tv_usec = 0;
                   1068: }
                   1069: 
                   1070: static void
                   1071: schedule_update_flush(struct interface *ifp, int urgent)
                   1072: {
                   1073:     babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
                   1074:     unsigned msecs;
                   1075:     msecs = update_jitter(babel_ifp, urgent);
                   1076:     if(babel_ifp->update_flush_timeout.tv_sec != 0 &&
                   1077:        timeval_minus_msec(&babel_ifp->update_flush_timeout, &babel_now) < msecs)
                   1078:         return;
                   1079:     set_timeout(&babel_ifp->update_flush_timeout, msecs);
                   1080: }
                   1081: 
                   1082: static void
                   1083: buffer_update(struct interface *ifp,
                   1084:               const unsigned char *prefix, unsigned char plen)
                   1085: {
                   1086:     babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
                   1087:     if(babel_ifp->num_buffered_updates > 0 &&
                   1088:        babel_ifp->num_buffered_updates >= babel_ifp->update_bufsize)
                   1089:         flushupdates(ifp);
                   1090: 
                   1091:     if(babel_ifp->update_bufsize == 0) {
                   1092:         int n;
                   1093:         assert(babel_ifp->buffered_updates == NULL);
                   1094:         /* Allocate enough space to hold a full update.  Since the
                   1095:            number of installed routes will grow over time, make sure we
                   1096:            have enough space to send a full-ish frame. */
                   1097:         n = installed_routes_estimate() + xroutes_estimate() + 4;
                   1098:         n = MAX(n, babel_ifp->bufsize / 16);
                   1099:     again:
                   1100:         babel_ifp->buffered_updates = malloc(n *sizeof(struct buffered_update));
                   1101:         if(babel_ifp->buffered_updates == NULL) {
                   1102:             zlog_err("malloc(buffered_updates): %s", safe_strerror(errno));
                   1103:             if(n > 4) {
                   1104:                 /* Try again with a tiny buffer. */
                   1105:                 n = 4;
                   1106:                 goto again;
                   1107:             }
                   1108:             return;
                   1109:         }
                   1110:         babel_ifp->update_bufsize = n;
                   1111:         babel_ifp->num_buffered_updates = 0;
                   1112:     }
                   1113: 
                   1114:     memcpy(babel_ifp->buffered_updates[babel_ifp->num_buffered_updates].prefix,
                   1115:            prefix, 16);
                   1116:     babel_ifp->buffered_updates[babel_ifp->num_buffered_updates].plen = plen;
                   1117:     babel_ifp->num_buffered_updates++;
                   1118: }
                   1119: 
                   1120: static void
                   1121: buffer_update_callback(struct babel_route *route, void *closure)
                   1122: {
                   1123:     buffer_update((struct interface*)closure,
                   1124:                   route->src->prefix, route->src->plen);
                   1125: }
                   1126: 
                   1127: void
                   1128: send_update(struct interface *ifp, int urgent,
                   1129:             const unsigned char *prefix, unsigned char plen)
                   1130: {
                   1131:     babel_interface_nfo *babel_ifp = NULL;
                   1132: 
                   1133:     if(ifp == NULL) {
                   1134:       struct interface *ifp_aux;
                   1135:       struct listnode *linklist_node = NULL;
                   1136:         struct babel_route *route;
                   1137:         FOR_ALL_INTERFACES(ifp_aux, linklist_node)
                   1138:             send_update(ifp_aux, urgent, prefix, plen);
                   1139:         if(prefix) {
                   1140:             /* Since flushupdates only deals with non-wildcard interfaces, we
                   1141:                need to do this now. */
                   1142:             route = find_installed_route(prefix, plen);
                   1143:             if(route && route_metric(route) < INFINITY)
                   1144:                 satisfy_request(prefix, plen, route->src->seqno, route->src->id,
                   1145:                                 NULL);
                   1146:         }
                   1147:         return;
                   1148:     }
                   1149: 
                   1150:     if(!if_up(ifp))
                   1151:         return;
                   1152: 
                   1153:     babel_ifp = babel_get_if_nfo(ifp);
                   1154:     if(prefix) {
                   1155:         debugf(BABEL_DEBUG_COMMON,"Sending update to %s for %s.",
                   1156:                ifp->name, format_prefix(prefix, plen));
                   1157:         buffer_update(ifp, prefix, plen);
                   1158:     } else {
                   1159:         send_self_update(ifp);
                   1160:         debugf(BABEL_DEBUG_COMMON,"Sending update to %s for any.", ifp->name);
                   1161:         for_all_installed_routes(buffer_update_callback, ifp);
                   1162:         set_timeout(&babel_ifp->update_timeout, babel_ifp->update_interval);
                   1163:         babel_ifp->last_update_time = babel_now.tv_sec;
                   1164:     }
                   1165:     schedule_update_flush(ifp, urgent);
                   1166: }
                   1167: 
                   1168: void
                   1169: send_update_resend(struct interface *ifp,
                   1170:                    const unsigned char *prefix, unsigned char plen)
                   1171: {
                   1172:     assert(prefix != NULL);
                   1173: 
                   1174:     send_update(ifp, 1, prefix, plen);
                   1175:     record_resend(RESEND_UPDATE, prefix, plen, 0, 0, NULL, resend_delay);
                   1176: }
                   1177: 
                   1178: void
                   1179: send_wildcard_retraction(struct interface *ifp)
                   1180: {
                   1181:     babel_interface_nfo *babel_ifp = NULL;
                   1182:     if(ifp == NULL) {
                   1183:       struct interface *ifp_aux;
                   1184:       struct listnode *linklist_node = NULL;
                   1185:         FOR_ALL_INTERFACES(ifp_aux, linklist_node)
                   1186:             send_wildcard_retraction(ifp_aux);
                   1187:         return;
                   1188:     }
                   1189: 
                   1190:     if(!if_up(ifp))
                   1191:         return;
                   1192: 
                   1193:     babel_ifp = babel_get_if_nfo(ifp);
                   1194:     start_message(ifp, MESSAGE_UPDATE, 10);
                   1195:     accumulate_byte(ifp, 0);
                   1196:     accumulate_byte(ifp, 0x40);
                   1197:     accumulate_byte(ifp, 0);
                   1198:     accumulate_byte(ifp, 0);
                   1199:     accumulate_short(ifp, 0xFFFF);
                   1200:     accumulate_short(ifp, myseqno);
                   1201:     accumulate_short(ifp, 0xFFFF);
                   1202:     end_message(ifp, MESSAGE_UPDATE, 10);
                   1203: 
                   1204:     babel_ifp->have_buffered_id = 0;
                   1205: }
                   1206: 
                   1207: void
                   1208: update_myseqno()
                   1209: {
                   1210:     myseqno = seqno_plus(myseqno, 1);
                   1211:     seqno_time = babel_now;
                   1212: }
                   1213: 
                   1214: static void
                   1215: send_xroute_update_callback(struct xroute *xroute, void *closure)
                   1216: {
                   1217:     struct interface *ifp = (struct interface*)closure;
                   1218:     send_update(ifp, 0, xroute->prefix, xroute->plen);
                   1219: }
                   1220: 
                   1221: void
                   1222: send_self_update(struct interface *ifp)
                   1223: {
                   1224:     if(ifp == NULL) {
                   1225:       struct interface *ifp_aux;
                   1226:       struct listnode *linklist_node = NULL;
                   1227:         FOR_ALL_INTERFACES(ifp_aux, linklist_node) {
                   1228:             if(!if_up(ifp_aux))
                   1229:                 continue;
                   1230:             send_self_update(ifp_aux);
                   1231:         }
                   1232:         return;
                   1233:     }
                   1234: 
                   1235:     debugf(BABEL_DEBUG_COMMON,"Sending self update to %s.", ifp->name);
                   1236:     for_all_xroutes(send_xroute_update_callback, ifp);
                   1237: }
                   1238: 
                   1239: void
                   1240: send_ihu(struct neighbour *neigh, struct interface *ifp)
                   1241: {
                   1242:     babel_interface_nfo *babel_ifp = NULL;
                   1243:     int rxcost, interval;
                   1244:     int ll;
                   1245: 
                   1246:     if(neigh == NULL && ifp == NULL) {
                   1247:       struct interface *ifp_aux;
                   1248:       struct listnode *linklist_node = NULL;
                   1249:         FOR_ALL_INTERFACES(ifp_aux, linklist_node) {
                   1250:             if(if_up(ifp_aux))
                   1251:                 continue;
                   1252:             send_ihu(NULL, ifp_aux);
                   1253:         }
                   1254:         return;
                   1255:     }
                   1256: 
                   1257:     if(neigh == NULL) {
                   1258:         struct neighbour *ngh;
                   1259:         FOR_ALL_NEIGHBOURS(ngh) {
                   1260:             if(ngh->ifp == ifp)
                   1261:                 send_ihu(ngh, ifp);
                   1262:         }
                   1263:         return;
                   1264:     }
                   1265: 
                   1266: 
                   1267:     if(ifp && neigh->ifp != ifp)
                   1268:         return;
                   1269: 
                   1270:     ifp = neigh->ifp;
                   1271:     babel_ifp = babel_get_if_nfo(ifp);
                   1272:     if(!if_up(ifp))
                   1273:         return;
                   1274: 
                   1275:     rxcost = neighbour_rxcost(neigh);
                   1276:     interval = (babel_ifp->hello_interval * 3 + 9) / 10;
                   1277: 
                   1278:     /* Conceptually, an IHU is a unicast message.  We usually send them as
                   1279:        multicast, since this allows aggregation into a single packet and
                   1280:        avoids an ARP exchange.  If we already have a unicast message queued
                   1281:        for this neighbour, however, we might as well piggyback the IHU. */
                   1282:     debugf(BABEL_DEBUG_COMMON,"Sending %sihu %d on %s to %s.",
                   1283:            unicast_neighbour == neigh ? "unicast " : "",
                   1284:            rxcost,
                   1285:            neigh->ifp->name,
                   1286:            format_address(neigh->address));
                   1287: 
                   1288:     ll = linklocal(neigh->address);
                   1289: 
                   1290:     if(unicast_neighbour != neigh) {
                   1291:         start_message(ifp, MESSAGE_IHU, ll ? 14 : 22);
                   1292:         accumulate_byte(ifp, ll ? 3 : 2);
                   1293:         accumulate_byte(ifp, 0);
                   1294:         accumulate_short(ifp, rxcost);
                   1295:         accumulate_short(ifp, interval);
                   1296:         if(ll)
                   1297:             accumulate_bytes(ifp, neigh->address + 8, 8);
                   1298:         else
                   1299:             accumulate_bytes(ifp, neigh->address, 16);
                   1300:         end_message(ifp, MESSAGE_IHU, ll ? 14 : 22);
                   1301:     } else {
                   1302:         int rc;
                   1303:         rc = start_unicast_message(neigh, MESSAGE_IHU, ll ? 14 : 22);
                   1304:         if(rc < 0) return;
                   1305:         accumulate_unicast_byte(neigh, ll ? 3 : 2);
                   1306:         accumulate_unicast_byte(neigh, 0);
                   1307:         accumulate_unicast_short(neigh, rxcost);
                   1308:         accumulate_unicast_short(neigh, interval);
                   1309:         if(ll)
                   1310:             accumulate_unicast_bytes(neigh, neigh->address + 8, 8);
                   1311:         else
                   1312:             accumulate_unicast_bytes(neigh, neigh->address, 16);
                   1313:         end_unicast_message(neigh, MESSAGE_IHU, ll ? 14 : 22);
                   1314:     }
                   1315: }
                   1316: 
                   1317: /* Send IHUs to all marginal neighbours */
                   1318: void
                   1319: send_marginal_ihu(struct interface *ifp)
                   1320: {
                   1321:     struct neighbour *neigh;
                   1322:     FOR_ALL_NEIGHBOURS(neigh) {
                   1323:         if(ifp && neigh->ifp != ifp)
                   1324:             continue;
                   1325:         if(neigh->txcost >= 384 || (neigh->reach & 0xF000) != 0xF000)
                   1326:             send_ihu(neigh, ifp);
                   1327:     }
                   1328: }
                   1329: 
                   1330: void
                   1331: send_request(struct interface *ifp,
                   1332:              const unsigned char *prefix, unsigned char plen)
                   1333: {
                   1334:     int v4, len;
                   1335: 
                   1336:     if(ifp == NULL) {
                   1337:       struct interface *ifp_aux;
                   1338:       struct listnode *linklist_node = NULL;
                   1339:         FOR_ALL_INTERFACES(ifp_aux, linklist_node) {
                   1340:             if(if_up(ifp_aux))
                   1341:                 continue;
                   1342:             send_request(ifp_aux, prefix, plen);
                   1343:         }
                   1344:         return;
                   1345:     }
                   1346: 
                   1347:     /* make sure any buffered updates go out before this request. */
                   1348:     flushupdates(ifp);
                   1349: 
                   1350:     if(!if_up(ifp))
                   1351:         return;
                   1352: 
                   1353:     debugf(BABEL_DEBUG_COMMON,"sending request to %s for %s.",
                   1354:            ifp->name, prefix ? format_prefix(prefix, plen) : "any");
                   1355:     v4 = plen >= 96 && v4mapped(prefix);
                   1356:     len = !prefix ? 2 : v4 ? 6 : 18;
                   1357: 
                   1358:     start_message(ifp, MESSAGE_REQUEST, len);
                   1359:     accumulate_byte(ifp, !prefix ? 0 : v4 ? 1 : 2);
                   1360:     accumulate_byte(ifp, !prefix ? 0 : v4 ? plen - 96 : plen);
                   1361:     if(prefix) {
                   1362:         if(v4)
                   1363:             accumulate_bytes(ifp, prefix + 12, 4);
                   1364:         else
                   1365:             accumulate_bytes(ifp, prefix, 16);
                   1366:     }
                   1367:     end_message(ifp, MESSAGE_REQUEST, len);
                   1368: }
                   1369: 
                   1370: void
                   1371: send_unicast_request(struct neighbour *neigh,
                   1372:                      const unsigned char *prefix, unsigned char plen)
                   1373: {
                   1374:     int rc, v4, len;
                   1375: 
                   1376:     /* make sure any buffered updates go out before this request. */
                   1377:     flushupdates(neigh->ifp);
                   1378: 
                   1379:     debugf(BABEL_DEBUG_COMMON,"sending unicast request to %s for %s.",
                   1380:            format_address(neigh->address),
                   1381:            prefix ? format_prefix(prefix, plen) : "any");
                   1382:     v4 = plen >= 96 && v4mapped(prefix);
                   1383:     len = !prefix ? 2 : v4 ? 6 : 18;
                   1384: 
                   1385:     rc = start_unicast_message(neigh, MESSAGE_REQUEST, len);
                   1386:     if(rc < 0) return;
                   1387:     accumulate_unicast_byte(neigh, !prefix ? 0 : v4 ? 1 : 2);
                   1388:     accumulate_unicast_byte(neigh, !prefix ? 0 : v4 ? plen - 96 : plen);
                   1389:     if(prefix) {
                   1390:         if(v4)
                   1391:             accumulate_unicast_bytes(neigh, prefix + 12, 4);
                   1392:         else
                   1393:             accumulate_unicast_bytes(neigh, prefix, 16);
                   1394:     }
                   1395:     end_unicast_message(neigh, MESSAGE_REQUEST, len);
                   1396: }
                   1397: 
                   1398: void
                   1399: send_multihop_request(struct interface *ifp,
                   1400:                       const unsigned char *prefix, unsigned char plen,
                   1401:                       unsigned short seqno, const unsigned char *id,
                   1402:                       unsigned short hop_count)
                   1403: {
                   1404:     int v4, pb, len;
                   1405: 
                   1406:     /* Make sure any buffered updates go out before this request. */
                   1407:     flushupdates(ifp);
                   1408: 
                   1409:     if(ifp == NULL) {
                   1410:       struct interface *ifp_aux;
                   1411:       struct listnode *linklist_node = NULL;
                   1412:         FOR_ALL_INTERFACES(ifp_aux, linklist_node) {
                   1413:             if(!if_up(ifp_aux))
                   1414:                 continue;
                   1415:             send_multihop_request(ifp_aux, prefix, plen, seqno, id, hop_count);
                   1416:         }
                   1417:         return;
                   1418:     }
                   1419: 
                   1420:     if(!if_up(ifp))
                   1421:         return;
                   1422: 
                   1423:     debugf(BABEL_DEBUG_COMMON,"Sending request (%d) on %s for %s.",
                   1424:            hop_count, ifp->name, format_prefix(prefix, plen));
                   1425:     v4 = plen >= 96 && v4mapped(prefix);
                   1426:     pb = v4 ? ((plen - 96) + 7) / 8 : (plen + 7) / 8;
                   1427:     len = 6 + 8 + pb;
                   1428: 
                   1429:     start_message(ifp, MESSAGE_MH_REQUEST, len);
                   1430:     accumulate_byte(ifp, v4 ? 1 : 2);
                   1431:     accumulate_byte(ifp, v4 ? plen - 96 : plen);
                   1432:     accumulate_short(ifp, seqno);
                   1433:     accumulate_byte(ifp, hop_count);
                   1434:     accumulate_byte(ifp, 0);
                   1435:     accumulate_bytes(ifp, id, 8);
                   1436:     if(prefix) {
                   1437:         if(v4)
                   1438:             accumulate_bytes(ifp, prefix + 12, pb);
                   1439:         else
                   1440:             accumulate_bytes(ifp, prefix, pb);
                   1441:     }
                   1442:     end_message(ifp, MESSAGE_MH_REQUEST, len);
                   1443: }
                   1444: 
                   1445: void
                   1446: send_unicast_multihop_request(struct neighbour *neigh,
                   1447:                               const unsigned char *prefix, unsigned char plen,
                   1448:                               unsigned short seqno, const unsigned char *id,
                   1449:                               unsigned short hop_count)
                   1450: {
                   1451:     int rc, v4, pb, len;
                   1452: 
                   1453:     /* Make sure any buffered updates go out before this request. */
                   1454:     flushupdates(neigh->ifp);
                   1455: 
                   1456:     debugf(BABEL_DEBUG_COMMON,"Sending multi-hop request to %s for %s (%d hops).",
                   1457:            format_address(neigh->address),
                   1458:            format_prefix(prefix, plen), hop_count);
                   1459:     v4 = plen >= 96 && v4mapped(prefix);
                   1460:     pb = v4 ? ((plen - 96) + 7) / 8 : (plen + 7) / 8;
                   1461:     len = 6 + 8 + pb;
                   1462: 
                   1463:     rc = start_unicast_message(neigh, MESSAGE_MH_REQUEST, len);
                   1464:     if(rc < 0) return;
                   1465:     accumulate_unicast_byte(neigh, v4 ? 1 : 2);
                   1466:     accumulate_unicast_byte(neigh, v4 ? plen - 96 : plen);
                   1467:     accumulate_unicast_short(neigh, seqno);
                   1468:     accumulate_unicast_byte(neigh, hop_count);
                   1469:     accumulate_unicast_byte(neigh, 0);
                   1470:     accumulate_unicast_bytes(neigh, id, 8);
                   1471:     if(prefix) {
                   1472:         if(v4)
                   1473:             accumulate_unicast_bytes(neigh, prefix + 12, pb);
                   1474:         else
                   1475:             accumulate_unicast_bytes(neigh, prefix, pb);
                   1476:     }
                   1477:     end_unicast_message(neigh, MESSAGE_MH_REQUEST, len);
                   1478: }
                   1479: 
                   1480: void
                   1481: send_request_resend(struct neighbour *neigh,
                   1482:                     const unsigned char *prefix, unsigned char plen,
                   1483:                     unsigned short seqno, unsigned char *id)
                   1484: {
                   1485:     if(neigh)
                   1486:         send_unicast_multihop_request(neigh, prefix, plen, seqno, id, 127);
                   1487:     else
                   1488:         send_multihop_request(NULL, prefix, plen, seqno, id, 127);
                   1489: 
                   1490:     record_resend(RESEND_REQUEST, prefix, plen, seqno, id,
                   1491:                   neigh ? neigh->ifp : NULL, resend_delay);
                   1492: }
                   1493: 
                   1494: void
                   1495: handle_request(struct neighbour *neigh, const unsigned char *prefix,
                   1496:                unsigned char plen, unsigned char hop_count,
                   1497:                unsigned short seqno, const unsigned char *id)
                   1498: {
                   1499:     struct xroute *xroute;
                   1500:     struct babel_route *route;
                   1501:     struct neighbour *successor = NULL;
                   1502: 
                   1503:     xroute = find_xroute(prefix, plen);
                   1504:     route = find_installed_route(prefix, plen);
                   1505: 
                   1506:     if(xroute && (!route || xroute->metric <= kernel_metric)) {
                   1507:         if(hop_count > 0 && memcmp(id, myid, 8) == 0) {
                   1508:             if(seqno_compare(seqno, myseqno) > 0) {
                   1509:                 if(seqno_minus(seqno, myseqno) > 100) {
                   1510:                     /* Hopelessly out-of-date request */
                   1511:                     return;
                   1512:                 }
                   1513:                 update_myseqno();
                   1514:             }
                   1515:         }
                   1516:         send_update(neigh->ifp, 1, prefix, plen);
                   1517:         return;
                   1518:     }
                   1519: 
                   1520:     if(route &&
                   1521:        (memcmp(id, route->src->id, 8) != 0 ||
                   1522:         seqno_compare(seqno, route->seqno) <= 0)) {
                   1523:         send_update(neigh->ifp, 1, prefix, plen);
                   1524:         return;
                   1525:     }
                   1526: 
                   1527:     if(hop_count <= 1)
                   1528:         return;
                   1529: 
                   1530:     if(route && memcmp(id, route->src->id, 8) == 0 &&
                   1531:        seqno_minus(seqno, route->seqno) > 100) {
                   1532:         /* Hopelessly out-of-date */
                   1533:         return;
                   1534:     }
                   1535: 
                   1536:     if(request_redundant(neigh->ifp, prefix, plen, seqno, id))
                   1537:         return;
                   1538: 
                   1539:     /* Let's try to forward this request. */
                   1540:     if(route && route_metric(route) < INFINITY)
                   1541:         successor = route->neigh;
                   1542: 
                   1543:     if(!successor || successor == neigh) {
                   1544:         /* We were about to forward a request to its requestor.  Try to
                   1545:            find a different neighbour to forward the request to. */
                   1546:         struct babel_route *other_route;
                   1547: 
                   1548:         other_route = find_best_route(prefix, plen, 0, neigh);
                   1549:         if(other_route && route_metric(other_route) < INFINITY)
                   1550:             successor = other_route->neigh;
                   1551:     }
                   1552: 
                   1553:     if(!successor || successor == neigh)
                   1554:         /* Give up */
                   1555:         return;
                   1556: 
                   1557:     send_unicast_multihop_request(successor, prefix, plen, seqno, id,
                   1558:                                   hop_count - 1);
                   1559:     record_resend(RESEND_REQUEST, prefix, plen, seqno, id,
                   1560:                   neigh->ifp, 0);
                   1561: }

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