File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / tests / aspath_test.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:12 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    1: /* 
    2:  * Copyright (C) 2005 Sun Microsystems, Inc.
    3:  *
    4:  * This file is part of Quagga.
    5:  *
    6:  * Quagga is free software; you can redistribute it and/or modify it
    7:  * under the terms of the GNU General Public License as published by the
    8:  * Free Software Foundation; either version 2, or (at your option) any
    9:  * later version.
   10:  *
   11:  * Quagga is distributed in the hope that it will be useful, but
   12:  * WITHOUT ANY WARRANTY; without even the implied warranty of
   13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14:  * General Public License for more details.
   15:  *
   16:  * You should have received a copy of the GNU General Public License
   17:  * along with Quagga; see the file COPYING.  If not, write to the Free
   18:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   19:  * 02111-1307, USA.  
   20:  */
   21: 
   22: #include <zebra.h>
   23: 
   24: #include "vty.h"
   25: #include "stream.h"
   26: #include "privs.h"
   27: #include "filter.h"
   28: 
   29: #include "bgpd/bgpd.h"
   30: #include "bgpd/bgp_aspath.h"
   31: #include "bgpd/bgp_attr.h"
   32: 
   33: #define VT100_RESET "\x1b[0m"
   34: #define VT100_RED "\x1b[31m"
   35: #define VT100_GREEN "\x1b[32m"
   36: #define VT100_YELLOW "\x1b[33m"
   37: #define OK VT100_GREEN "OK" VT100_RESET
   38: #define FAILED VT100_RED "failed" VT100_RESET
   39: 
   40: /* need these to link in libbgp */
   41: struct zebra_privs_t *bgpd_privs = NULL;
   42: struct thread_master *master = NULL;
   43: 
   44: static int failed = 0;
   45: 
   46: /* specification for a test - what the results should be */
   47: struct test_spec 
   48: {
   49:   const char *shouldbe; /* the string the path should parse to */
   50:   const char *shouldbe_delete_confed; /* ditto, but once confeds are deleted */
   51:   const unsigned int hops; /* aspath_count_hops result */
   52:   const unsigned int confeds; /* aspath_count_confeds */
   53:   const int private_as; /* whether the private_as check should pass or fail */
   54: #define NOT_ALL_PRIVATE 0
   55: #define ALL_PRIVATE 1
   56:   const as_t does_loop; /* an ASN which should trigger loop-check */
   57:   const as_t doesnt_loop; /* one which should not */
   58:   const as_t first; /* the first ASN, if there is one */
   59: #define NULL_ASN 0
   60: };
   61: 
   62: 
   63: /* test segments to parse and validate, and use for other tests */
   64: static struct test_segment {
   65:   const char *name;
   66:   const char *desc;
   67:   const u_char asdata[1024];
   68:   int len;
   69:   struct test_spec sp;
   70: } test_segments [] = 
   71: {
   72:   { /* 0 */ 
   73:     "seq1",
   74:     "seq(8466,3,52737,4096)",
   75:     { 0x2,0x4, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00 },
   76:     10,
   77:     { "8466 3 52737 4096",
   78:       "8466 3 52737 4096",
   79:       4, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
   80:   },
   81:   { /* 1 */
   82:     "seq2",
   83:     "seq(8722) seq(4)",
   84:     { 0x2,0x1, 0x22,0x12,
   85:       0x2,0x1, 0x00,0x04 },
   86:     8,
   87:     { "8722 4",
   88:       "8722 4",
   89:       2, 0, NOT_ALL_PRIVATE, 4, 5, 8722, },
   90:   },
   91:   { /* 2 */
   92:     "seq3",
   93:     "seq(8466,3,52737,4096,8722,4)",
   94:     { 0x2,0x6, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 
   95:                0x22,0x12, 0x00,0x04},
   96:     14,
   97:     { "8466 3 52737 4096 8722 4",
   98:       "8466 3 52737 4096 8722 4",
   99:        6, 0, NOT_ALL_PRIVATE, 3, 5, 8466 },
  100:   },
  101:   { /* 3 */
  102:     "seqset",
  103:     "seq(8482,51457) set(5204)",
  104:     { 0x2,0x2, 0x21,0x22, 0xc9,0x01,
  105:       0x1,0x1, 0x14,0x54 },
  106:     10,
  107:     { "8482 51457 {5204}",
  108:       "8482 51457 {5204}",
  109:       3, 0, NOT_ALL_PRIVATE, 5204, 51456, 8482},
  110:   },
  111:   { /* 4 */
  112:     "seqset2",
  113:     "seq(8467, 59649) set(4196,48658) set(17322,30745)",
  114:     { 0x2,0x2, 0x21,0x13, 0xe9,0x01,
  115:       0x1,0x2, 0x10,0x64, 0xbe,0x12,
  116:       0x1,0x2, 0x43,0xaa, 0x78,0x19 },    
  117:     18,
  118:     { "8467 59649 {4196,48658} {17322,30745}",
  119:       "8467 59649 {4196,48658} {17322,30745}",
  120:       4, 0, NOT_ALL_PRIVATE, 48658, 1, 8467},
  121:   },
  122:   { /* 5 */
  123:     "multi",
  124:     "seq(6435,59408,21665) set(2457,61697,4369), seq(1842,41590,51793)",
  125:     { 0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1,
  126:       0x1,0x3, 0x09,0x99, 0xf1,0x01, 0x11,0x11,
  127:       0x2,0x3, 0x07,0x32, 0xa2,0x76, 0xca,0x51 },
  128:     24,
  129:     { "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
  130:       "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
  131:       7, 0, NOT_ALL_PRIVATE, 51793, 1, 6435 },
  132:   },
  133:   { /* 6 */
  134:     "confed",
  135:     "confseq(123,456,789)",
  136:     { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15 },
  137:     8,
  138:     { "(123 456 789)",
  139:       "",
  140:       0, 3, NOT_ALL_PRIVATE, 789, 1, NULL_ASN },
  141:   },
  142:   { /* 7 */
  143:     "confed2",
  144:     "confseq(123,456,789) confseq(111,222)",
  145:     { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15,
  146:       0x3,0x2, 0x00,0x6f, 0x00,0xde },
  147:     14,
  148:     { "(123 456 789) (111 222)",
  149:       "",
  150:       0, 5, NOT_ALL_PRIVATE, 111, 1, NULL_ASN },
  151:   },
  152:   { /* 8 */
  153:     "confset",
  154:     "confset(456,123,789)",
  155:     { 0x4,0x3, 0x01,0xc8, 0x00,0x7b, 0x03,0x15 },
  156:     8,
  157:     { "[123,456,789]",
  158:       "[123,456,789]",
  159:       0, 1, NOT_ALL_PRIVATE, 123, 1, NULL_ASN },
  160:   },
  161:   { /* 9 */
  162:     "confmulti",
  163:     "confseq(123,456,789) confset(222,111) seq(8722) set(4196,48658)",
  164:     { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15,
  165:       0x4,0x2, 0x00,0xde, 0x00,0x6f,
  166:       0x2,0x1, 0x22,0x12,
  167:       0x1,0x2, 0x10,0x64, 0xbe,0x12 },
  168:     24,
  169:     { "(123 456 789) [111,222] 8722 {4196,48658}",
  170:       "8722 {4196,48658}",
  171:       2, 4, NOT_ALL_PRIVATE, 123, 1, NULL_ASN },
  172:   },
  173:   { /* 10 */
  174:     "seq4",
  175:     "seq(8466,2,52737,4096,8722,4)",
  176:     { 0x2,0x6, 0x21,0x12, 0x00,0x02, 0xce,0x01, 0x10,0x00, 
  177:                0x22,0x12, 0x00,0x04},
  178:     14,
  179:     { "8466 2 52737 4096 8722 4",
  180:       "8466 2 52737 4096 8722 4",
  181:       6, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
  182:   },
  183:   { /* 11 */
  184:     "tripleseq1",
  185:     "seq(8466,2,52737) seq(4096,8722,4) seq(8722)",
  186:     { 0x2,0x3, 0x21,0x12, 0x00,0x02, 0xce,0x01, 
  187:       0x2,0x3, 0x10,0x00, 0x22,0x12, 0x00,0x04,
  188:       0x2,0x1, 0x22,0x12},
  189:     20,
  190:     { "8466 2 52737 4096 8722 4 8722",
  191:       "8466 2 52737 4096 8722 4 8722",
  192:       7, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
  193:   },
  194:   { /* 12 */ 
  195:     "someprivate",
  196:     "seq(8466,64512,52737,65535)",
  197:     { 0x2,0x4, 0x21,0x12, 0xfc,0x00, 0xce,0x01, 0xff,0xff },
  198:     10,
  199:     { "8466 64512 52737 65535",
  200:       "8466 64512 52737 65535",
  201:       4, 0, NOT_ALL_PRIVATE, 65535, 4, 8466 },
  202:   },
  203:   { /* 13 */ 
  204:     "allprivate",
  205:     "seq(65534,64512,64513,65535)",
  206:     { 0x2,0x4, 0xff,0xfe, 0xfc,0x00, 0xfc,0x01, 0xff,0xff },
  207:     10,
  208:     { "65534 64512 64513 65535",
  209:       "65534 64512 64513 65535",
  210:       4, 0, ALL_PRIVATE, 65534, 4, 65534 },
  211:   },
  212:   { /* 14 */ 
  213:     "long",
  214:     "seq(8466,3,52737,4096,34285,<repeated 49 more times>)",
  215:     { 0x2,0xfa, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  216:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  217:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  218:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  219:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  220:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  221:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  222:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  223:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  224:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  225:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  226:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  227:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  228:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  229:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  230:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  231:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  232:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  233:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  234:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  235:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  236:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  237:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  238:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  239:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  240:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  241:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  242:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  243:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  244:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  245:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  246:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  247:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  248:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  249:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  250:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  251:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  252:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  253:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  254:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  255:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  256:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  257:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  258:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  259:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  260:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  261:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  262:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  263:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
  264:                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed, },
  265:     502,
  266:     { "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  267:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  268:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  269:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  270:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  271:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  272:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  273:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  274:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  275:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  276:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  277:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  278:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  279:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  280:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  281:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  282:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  283:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  284:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  285:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  286:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  287:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  288:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  289:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  290:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285",
  291:       
  292:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  293:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  294:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  295:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  296:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  297:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  298:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  299:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  300:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  301:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  302:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  303:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  304:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  305:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  306:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  307:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  308:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  309:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  310:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  311:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  312:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  313:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  314:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  315:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  316:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285",
  317:       250, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
  318:   },
  319:   { /* 15 */ 
  320:     "seq1extra",
  321:     "seq(8466,3,52737,4096,3456)",
  322:     { 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80 },
  323:     12,
  324:     { "8466 3 52737 4096 3456",
  325:       "8466 3 52737 4096 3456",
  326:       5, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
  327:   },
  328:   { /* 16 */
  329:     "empty",
  330:     "<empty>",
  331:     {},
  332:     0,
  333:     { "", "", 0, 0, 0, 0, 0, 0 },
  334:   },
  335:   { /* 17 */ 
  336:     "redundantset",
  337:     "seq(8466,3,52737,4096,3456) set(7099,8153,8153,8153)",
  338:     { 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80,
  339:       0x1,0x4, 0x1b,0xbb, 0x1f,0xd9, 0x1f,0xd9, 0x1f,0xd9 },
  340:     22,
  341:     {
  342:      /* We shouldn't ever /generate/ such paths. However, we should
  343:       * cope with them fine.
  344:       */
  345:      "8466 3 52737 4096 3456 {7099,8153}",
  346:       "8466 3 52737 4096 3456 {7099,8153}",
  347:       6, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
  348:   },
  349:   { /* 18 */
  350:     "reconcile_lead_asp",
  351:     "seq(6435,59408,21665) set(23456,23456,23456), seq(23456,23456,23456)",
  352:     { 0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1,
  353:       0x1,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0,
  354:       0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0 },
  355:     24,
  356:     { "6435 59408 21665 {23456} 23456 23456 23456",
  357:       "6435 59408 21665 {23456} 23456 23456 23456",
  358:       7, 0, NOT_ALL_PRIVATE, 23456, 1, 6435 },
  359:   },
  360:   { /* 19 */
  361:     "reconcile_new_asp",
  362:     "set(2457,61697,4369), seq(1842,41591,51793)",
  363:     { 
  364:       0x1,0x3, 0x09,0x99, 0xf1,0x01, 0x11,0x11,
  365:       0x2,0x3, 0x07,0x32, 0xa2,0x77, 0xca,0x51 },
  366:     16,
  367:     { "{2457,4369,61697} 1842 41591 51793",
  368:       "{2457,4369,61697} 1842 41591 51793",
  369:       4, 0, NOT_ALL_PRIVATE, 51793, 1, 2457 },
  370:   },
  371:   { /* 20 */
  372:     "reconcile_confed",
  373:     "confseq(123,456,789) confset(456,124,788) seq(6435,59408,21665)"
  374:     " set(23456,23456,23456), seq(23456,23456,23456)",
  375:     { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15,
  376:       0x4,0x3, 0x01,0xc8, 0x00,0x7c, 0x03,0x14,
  377:       0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1,
  378:       0x1,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0,
  379:       0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0 },
  380:     40,
  381:     { "(123 456 789) [124,456,788] 6435 59408 21665"
  382:       " {23456} 23456 23456 23456",
  383:       "6435 59408 21665 {23456} 23456 23456 23456",
  384:       7, 4, NOT_ALL_PRIVATE, 23456, 1, 6435 },
  385:   },
  386:   { /* 21 */
  387:     "reconcile_start_trans",
  388:     "seq(23456,23456,23456) seq(6435,59408,21665)",
  389:     { 0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0,
  390:       0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1, },
  391:     16,
  392:     { "23456 23456 23456 6435 59408 21665",
  393:       "23456 23456 23456 6435 59408 21665",
  394:       6, 0, NOT_ALL_PRIVATE, 21665, 1, 23456 },
  395:   },
  396:   { /* 22 */
  397:     "reconcile_start_trans4",
  398:     "seq(1842,41591,51793) seq(6435,59408,21665)",
  399:     { 0x2,0x3, 0x07,0x32, 0xa2,0x77, 0xca,0x51,
  400:       0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1, },
  401:     16,
  402:     { "1842 41591 51793 6435 59408 21665",
  403:       "1842 41591 51793 6435 59408 21665",
  404:       6, 0, NOT_ALL_PRIVATE, 41591, 1, 1842 },
  405:   },
  406:   { /* 23 */
  407:     "reconcile_start_trans_error",
  408:     "seq(23456,23456,23456) seq(6435,59408)",
  409:     { 0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0,
  410:       0x2,0x2, 0x19,0x23, 0xe8,0x10, },
  411:     14,
  412:     { "23456 23456 23456 6435 59408",
  413:       "23456 23456 23456 6435 59408",
  414:       5, 0, NOT_ALL_PRIVATE, 59408, 1, 23456 },
  415:   },
  416:   { /* 24 */ 
  417:     "redundantset2",
  418:     "seq(8466,3,52737,4096,3456) set(7099,8153,8153,8153,7099)",
  419:     { 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80,
  420:       0x1,0x5, 0x1b,0xbb, 0x1f,0xd9, 0x1f,0xd9, 0x1f,0xd9, 0x1b,0xbb,},
  421:     24,
  422:     {
  423:      /* We should weed out duplicate set members. */
  424:      "8466 3 52737 4096 3456 {7099,8153}",
  425:       "8466 3 52737 4096 3456 {7099,8153}",
  426:       6, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
  427:   },
  428:   { /* 25 */ 
  429:     "zero-size overflow",
  430:     "#ASNs = 0, data = seq(8466 3 52737 4096 3456)",
  431:     { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80 },
  432:     12,
  433:     { NULL, NULL,
  434:       0, 0, 0, 0, 0, 0 },
  435:   },
  436:   { /* 26  */ 
  437:     "zero-size overflow + valid segment",
  438:     "seq(#AS=0:8466 3 52737),seq(4096 3456)",
  439:     { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01, 
  440:       0x2,0x2, 0x10,0x00, 0x0d,0x80 },
  441:     14
  442:     ,
  443:     { NULL, NULL,
  444:       0, 0, 0, 0, 0, 0 },
  445:   },
  446:   { /* 27  */ 
  447:     "invalid segment type",
  448:     "type=8(4096 3456)",
  449:     { 0x8,0x2, 0x10,0x00, 0x0d,0x80 },
  450:     14
  451:     ,
  452:     { NULL, NULL,
  453:       0, 0, 0, 0, 0, 0 },
  454:   },  { NULL, NULL, {0}, 0, { NULL, 0, 0 } }
  455: };
  456: 
  457: #define COMMON_ATTRS \
  458:       BGP_ATTR_FLAG_TRANS, \
  459:       BGP_ATTR_ORIGIN, \
  460:       1, \
  461:       BGP_ORIGIN_EGP, \
  462:       BGP_ATTR_FLAG_TRANS, \
  463:       BGP_ATTR_NEXT_HOP, \
  464:       4, 192, 0, 2, 0
  465: #define COMMON_ATTR_SIZE 11
  466: 
  467: /* */
  468: static struct aspath_tests {
  469:   const char *desc;
  470:   const struct test_segment *segment;
  471:   const char *shouldbe;  /* String it should evaluate to */
  472:   const enum as4 { AS4_DATA, AS2_DATA }
  473:           as4; 	/* whether data should be as4 or not (ie as2) */
  474:   const int result;	/* expected result for bgp_attr_parse */
  475:   const int cap;	/* capabilities to set for peer */
  476:   const char attrheader [1024];
  477:   size_t len;
  478:   const struct test_segment *old_segment;
  479: } aspath_tests [] =
  480: {
  481:   /* 0 */
  482:   {
  483:     "basic test",
  484:     &test_segments[0],
  485:     "8466 3 52737 4096",
  486:     AS2_DATA, 0,
  487:     0,
  488:     { COMMON_ATTRS,
  489:       BGP_ATTR_FLAG_TRANS,
  490:       BGP_ATTR_AS_PATH,
  491:       10,
  492:     },
  493:     COMMON_ATTR_SIZE + 3,
  494:   },
  495:   /* 1 */
  496:   {
  497:     "length too short",
  498:     &test_segments[0],
  499:     "8466 3 52737 4096",
  500:     AS2_DATA, -1,
  501:     0,
  502:     { COMMON_ATTRS,
  503:       BGP_ATTR_FLAG_TRANS,
  504:       BGP_ATTR_AS_PATH, 
  505:       8,
  506:     },
  507:     COMMON_ATTR_SIZE + 3,
  508:   },
  509:   /* 2 */
  510:   {
  511:     "length too long",
  512:     &test_segments[0],
  513:     "8466 3 52737 4096",
  514:     AS2_DATA, -1,
  515:     0,
  516:     { COMMON_ATTRS,
  517:       BGP_ATTR_FLAG_TRANS,
  518:       BGP_ATTR_AS_PATH, 
  519:       12,
  520:     },
  521:     COMMON_ATTR_SIZE + 3,
  522:   },
  523:   /* 3 */
  524:   {
  525:     "incorrect flag",
  526:     &test_segments[0],
  527:     "8466 3 52737 4096",
  528:     AS2_DATA, -1,
  529:     0,
  530:     { COMMON_ATTRS,
  531:       BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
  532:       BGP_ATTR_AS_PATH, 
  533:       10,
  534:     },
  535:     COMMON_ATTR_SIZE + 3,
  536:   },
  537:   /* 4 */
  538:   {
  539:     "as4_path, with as2 format data",
  540:     &test_segments[0],
  541:     "8466 3 52737 4096",
  542:     AS2_DATA, -1,
  543:     0,
  544:     { COMMON_ATTRS,
  545:       BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
  546:       BGP_ATTR_AS4_PATH, 
  547:       10,
  548:     },
  549:     COMMON_ATTR_SIZE + 3,
  550:   },
  551:   /* 5 */
  552:   {
  553:     "as4, with incorrect attr length",
  554:     &test_segments[0],
  555:     "8466 3 52737 4096",
  556:     AS4_DATA, -1,
  557:     PEER_CAP_AS4_RCV,
  558:     { COMMON_ATTRS,
  559:       BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
  560:       BGP_ATTR_AS4_PATH, 
  561:       10,
  562:     },
  563:     COMMON_ATTR_SIZE + 3,
  564:   },
  565:   /* 6 */
  566:   {
  567:     "basic 4-byte as-path",
  568:     &test_segments[0],
  569:     "8466 3 52737 4096",
  570:     AS4_DATA, 0,
  571:     PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
  572:     { COMMON_ATTRS,
  573:       BGP_ATTR_FLAG_TRANS,
  574:       BGP_ATTR_AS_PATH, 
  575:       18,
  576:     },
  577:     COMMON_ATTR_SIZE + 3,
  578:   },
  579:   /* 7 */
  580:   {
  581:     "4b AS_PATH: too short",
  582:     &test_segments[0],
  583:     "8466 3 52737 4096",
  584:     AS4_DATA, -1,
  585:     PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
  586:     { COMMON_ATTRS,
  587:       BGP_ATTR_FLAG_TRANS,
  588:       BGP_ATTR_AS_PATH, 
  589:       16,
  590:     },
  591:     COMMON_ATTR_SIZE + 3,
  592:   },
  593:   /* 8 */
  594:   {
  595:     "4b AS_PATH: too long",
  596:     &test_segments[0],
  597:     "8466 3 52737 4096",
  598:     AS4_DATA, -1,
  599:     PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
  600:     { COMMON_ATTRS,
  601:       BGP_ATTR_FLAG_TRANS,
  602:       BGP_ATTR_AS_PATH, 
  603:       20,
  604:     },
  605:     COMMON_ATTR_SIZE + 3,
  606:   },
  607:   /* 9 */
  608:   {
  609:     "4b AS_PATH: too long2",
  610:     &test_segments[0],
  611:     "8466 3 52737 4096",
  612:     AS4_DATA, -1,
  613:     PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
  614:     { COMMON_ATTRS,
  615:       BGP_ATTR_FLAG_TRANS,
  616:       BGP_ATTR_AS_PATH, 
  617:       22,
  618:     },
  619:     COMMON_ATTR_SIZE + 3,
  620:   },
  621:   /* 10 */
  622:   {
  623:     "4b AS_PATH: bad flags",
  624:     &test_segments[0],
  625:     "8466 3 52737 4096",
  626:     AS4_DATA, -1,
  627:     PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
  628:     { COMMON_ATTRS,
  629:       BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
  630:       BGP_ATTR_AS_PATH, 
  631:       18,
  632:     },
  633:     COMMON_ATTR_SIZE + 3,
  634:   },
  635:   /* 11 */
  636:   {
  637:     "4b AS4_PATH w/o AS_PATH",
  638:     &test_segments[6],
  639:     NULL,
  640:     AS4_DATA, -1,
  641:     PEER_CAP_AS4_ADV,
  642:     { COMMON_ATTRS,
  643:       BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
  644:       BGP_ATTR_AS4_PATH, 
  645:       14,
  646:     },
  647:     COMMON_ATTR_SIZE + 3,
  648:   },
  649:   /* 12 */
  650:   {
  651:     "4b AS4_PATH: confed",
  652:     &test_segments[6],
  653:     "8466 3 52737 4096 (123 456 789)",
  654:     AS4_DATA, 0,
  655:     PEER_CAP_AS4_ADV,
  656:     { COMMON_ATTRS,
  657:       BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
  658:       BGP_ATTR_AS4_PATH, 
  659:       14,
  660:     },
  661:     COMMON_ATTR_SIZE + 3,
  662:     &test_segments[0],
  663:   },
  664:   { NULL, NULL, NULL, 0, 0, 0, { 0 }, 0 },
  665: };
  666: 
  667: /* prepending tests */
  668: static struct tests {
  669:   const struct test_segment *test1;
  670:   const struct test_segment *test2;
  671:   struct test_spec sp;
  672: } prepend_tests[] = 
  673: {
  674:   /* 0 */
  675:   { &test_segments[0], &test_segments[1],
  676:     { "8466 3 52737 4096 8722 4",
  677:       "8466 3 52737 4096 8722 4",
  678:       6, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
  679:   },
  680:   /* 1 */
  681:   { &test_segments[1], &test_segments[3],
  682:     { "8722 4 8482 51457 {5204}",
  683:       "8722 4 8482 51457 {5204}",
  684:       5, 0, NOT_ALL_PRIVATE, 5204, 1, 8722 }
  685:   },
  686:   /* 2 */
  687:   { &test_segments[3], &test_segments[4],
  688:     { "8482 51457 {5204} 8467 59649 {4196,48658} {17322,30745}",
  689:       "8482 51457 {5204} 8467 59649 {4196,48658} {17322,30745}",
  690:       7, 0, NOT_ALL_PRIVATE, 5204, 1, 8482 },
  691:   },
  692:   /* 3 */
  693:   { &test_segments[4], &test_segments[5],
  694:     { "8467 59649 {4196,48658} {17322,30745} 6435 59408 21665"
  695:       " {2457,4369,61697} 1842 41590 51793",
  696:       "8467 59649 {4196,48658} {17322,30745} 6435 59408 21665"
  697:       " {2457,4369,61697} 1842 41590 51793",
  698:       11, 0, NOT_ALL_PRIVATE, 61697, 1, 8467 }
  699:   },
  700:   /* 4 */
  701:   { &test_segments[5], &test_segments[6],
  702:     { "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
  703:       "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
  704:       7, 0, NOT_ALL_PRIVATE, 1842, 1, 6435 },
  705:   },
  706:   /* 5 */
  707:   { &test_segments[6], &test_segments[7],
  708:     { "(123 456 789) (123 456 789) (111 222)",
  709:       "",
  710:       0, 8, NOT_ALL_PRIVATE, 111, 1, 0 }
  711:   },
  712:   { &test_segments[7], &test_segments[8],
  713:     { "(123 456 789) (111 222) [123,456,789]",
  714:       "",
  715:       0, 6, NOT_ALL_PRIVATE, 111, 1, 0 }
  716:   },
  717:   { &test_segments[8], &test_segments[9],
  718:     { "[123,456,789] (123 456 789) [111,222] 8722 {4196,48658}",
  719:       "[123,456,789] (123 456 789) [111,222] 8722 {4196,48658}",
  720:       2, 5, NOT_ALL_PRIVATE, 456, 1, NULL_ASN },
  721:   },
  722:   { &test_segments[9], &test_segments[8],
  723:     { "(123 456 789) [111,222] 8722 {4196,48658} [123,456,789]",
  724:       "8722 {4196,48658} [123,456,789]",
  725:       2, 5, NOT_ALL_PRIVATE, 48658, 1, NULL_ASN },
  726:   },
  727:   { &test_segments[14], &test_segments[11],
  728:     { "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  729:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  730:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  731:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  732:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  733:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  734:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  735:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  736:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  737:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  738:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  739:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  740:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  741:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  742:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  743:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  744:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  745:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  746:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  747:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  748:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  749:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  750:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  751:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  752:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  753:       "8466 2 52737 4096 8722 4 8722",
  754:       
  755:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  756:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  757:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  758:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  759:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  760:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  761:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  762:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  763:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  764:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  765:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  766:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  767:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  768:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  769:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  770:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  771:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  772:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  773:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  774:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  775:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  776:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  777:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  778:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  779:       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
  780:       "8466 2 52737 4096 8722 4 8722",
  781:       257, 0, NOT_ALL_PRIVATE, 4096, 1000, 8466 },
  782:   },
  783:   { NULL, NULL, { NULL, 0, 0, 0, 0, 0, 0, } },
  784: };
  785: 
  786: struct tests reconcile_tests[] =
  787: {
  788:   { &test_segments[18], &test_segments[19],
  789:     { "6435 59408 21665 {2457,4369,61697} 1842 41591 51793",
  790:       "6435 59408 21665 {2457,4369,61697} 1842 41591 51793",
  791:       7, 0, NOT_ALL_PRIVATE, 51793, 1, 6435 },
  792:   },
  793:   { &test_segments[19], &test_segments[18],
  794:     /* AS_PATH (19) has more hops than NEW_AS_PATH,
  795:      * so just AS_PATH should be used (though, this practice
  796:      * is bad imho).
  797:      */
  798:     { "{2457,4369,61697} 1842 41591 51793 6435 59408 21665 {23456} 23456 23456 23456",
  799:       "{2457,4369,61697} 1842 41591 51793 6435 59408 21665 {23456} 23456 23456 23456",
  800:       11, 0, NOT_ALL_PRIVATE, 51793, 1, 6435 },
  801:   },
  802:   { &test_segments[20], &test_segments[19],
  803:     { "(123 456 789) [124,456,788] 6435 59408 21665"
  804:       " {2457,4369,61697} 1842 41591 51793",
  805:       "6435 59408 21665 {2457,4369,61697} 1842 41591 51793",
  806:       7, 4, NOT_ALL_PRIVATE, 51793, 1, 6435 },
  807:   },
  808:   { &test_segments[21], &test_segments[22],
  809:     { "1842 41591 51793 6435 59408 21665",
  810:       "1842 41591 51793 6435 59408 21665",
  811:       6, 0, NOT_ALL_PRIVATE, 51793, 1, 1842 },
  812:   },
  813:   { &test_segments[23], &test_segments[22],
  814:     { "23456 23456 23456 6435 59408 1842 41591 51793 6435 59408 21665",
  815:       "23456 23456 23456 6435 59408 1842 41591 51793 6435 59408 21665",
  816:       11, 0, NOT_ALL_PRIVATE, 51793, 1, 1842 },
  817:   },
  818:   { NULL, NULL, { NULL, 0, 0, 0, 0, 0, 0, } },
  819: };
  820:   
  821: struct tests aggregate_tests[] =
  822: {
  823:   { &test_segments[0], &test_segments[2],
  824:     { "8466 3 52737 4096 {4,8722}",
  825:       "8466 3 52737 4096 {4,8722}",
  826:       5, 0, NOT_ALL_PRIVATE, 4, 1, 8466 },
  827:   },
  828:   { &test_segments[2], &test_segments[0],
  829:     { "8466 3 52737 4096 {4,8722}",
  830:       "8466 3 52737 4096 {4,8722}",
  831:       5, 0, NOT_ALL_PRIVATE, 8722, 1, 8466 },
  832:   },
  833:   { &test_segments[2], &test_segments[10],
  834:     { "8466 {2,3,4,4096,8722,52737}",
  835:       "8466 {2,3,4,4096,8722,52737}",
  836:       2, 0, NOT_ALL_PRIVATE, 8722, 5, 8466 },
  837:   },
  838:   { &test_segments[10], &test_segments[2],
  839:     { "8466 {2,3,4,4096,8722,52737}",
  840:       "8466 {2,3,4,4096,8722,52737}",
  841:       2, 0, NOT_ALL_PRIVATE, 2, 20000, 8466 },
  842:   },
  843: 
  844:   { &test_segments[5], &test_segments[18],
  845:     { "6435 59408 21665 {1842,2457,4369,23456,41590,51793,61697}",
  846:       "6435 59408 21665 {1842,2457,4369,23456,41590,51793,61697}",
  847:       4, 0, NOT_ALL_PRIVATE, 41590, 1, 6435 },
  848:   },
  849: 
  850:   { NULL, NULL, { NULL, 0, 0}  },
  851: };
  852: 
  853: struct compare_tests 
  854: {
  855:   int test_index1;
  856:   int test_index2;
  857: #define CMP_RES_YES 1
  858: #define CMP_RES_NO 0
  859:   char shouldbe_cmp;
  860:   char shouldbe_confed;
  861: } left_compare [] =
  862: {
  863:   { 0, 1, CMP_RES_NO, CMP_RES_NO },
  864:   { 0, 2, CMP_RES_YES, CMP_RES_NO },
  865:   { 0, 11, CMP_RES_YES, CMP_RES_NO },
  866:   { 0, 15, CMP_RES_YES, CMP_RES_NO },
  867:   { 0, 16, CMP_RES_NO, CMP_RES_NO },
  868:   { 1, 11, CMP_RES_NO, CMP_RES_NO },
  869:   { 6, 7, CMP_RES_NO, CMP_RES_YES },
  870:   { 6, 8, CMP_RES_NO, CMP_RES_NO },
  871:   { 7, 8, CMP_RES_NO, CMP_RES_NO },
  872:   { 1, 9, CMP_RES_YES, CMP_RES_NO },
  873:   { 0, 9, CMP_RES_NO, CMP_RES_NO },
  874:   { 3, 9, CMP_RES_NO, CMP_RES_NO },
  875:   { 0, 6, CMP_RES_NO, CMP_RES_NO },
  876:   { 1, 6, CMP_RES_NO, CMP_RES_NO },
  877:   { 0, 8, CMP_RES_NO, CMP_RES_NO },
  878:   { 1, 8, CMP_RES_NO, CMP_RES_NO },
  879:   { 11, 6, CMP_RES_NO, CMP_RES_NO },
  880:   { 11, 7, CMP_RES_NO, CMP_RES_NO },
  881:   { 11, 8, CMP_RES_NO, CMP_RES_NO },
  882:   { 9, 6, CMP_RES_NO, CMP_RES_YES },
  883:   { 9, 7, CMP_RES_NO, CMP_RES_YES },
  884:   { 9, 8, CMP_RES_NO, CMP_RES_NO },
  885: };
  886: 
  887: /* make an aspath from a data stream */
  888: static struct aspath *
  889: make_aspath (const u_char *data, size_t len, int use32bit)
  890: {
  891:   struct stream *s = NULL;
  892:   struct aspath *as;
  893:   
  894:   if (len)
  895:     {
  896:       s = stream_new (len);
  897:       stream_put (s, data, len);
  898:     }
  899:   as = aspath_parse (s, len, use32bit);
  900:   
  901:   if (s)
  902:     stream_free (s);
  903:   
  904:   return as;
  905: }
  906: 
  907: static void
  908: printbytes (const u_char *bytes, int len)
  909: {
  910:   int i = 0;
  911:   while (i < len)
  912:     {
  913:       if (i % 2)
  914:         printf ("%02hhx%s", bytes[i], " ");
  915:       else
  916:         printf ("0x%02hhx", bytes[i]);
  917:       i++;
  918:     }
  919:   printf ("\n");
  920: }  
  921: 
  922: /* validate the given aspath */
  923: static int
  924: validate (struct aspath *as, const struct test_spec *sp)
  925: {
  926:   size_t bytes, bytes4;
  927:   int fails = 0;
  928:   const u_char *out;
  929:   static struct stream *s;
  930:   struct aspath *asinout, *asconfeddel, *asstr, *as4;
  931:   
  932:   if (as == NULL && sp->shouldbe == NULL)
  933:     {
  934:       printf ("Correctly failed to parse\n");
  935:       return fails;
  936:     }
  937:   
  938:   out = aspath_snmp_pathseg (as, &bytes);
  939:   asinout = make_aspath (out, bytes, 0);
  940:   
  941:   /* Excercise AS4 parsing a bit, with a dogfood test */
  942:   if (!s)
  943:     s = stream_new (4096);
  944:   bytes4 = aspath_put (s, as, 1);
  945:   as4 = make_aspath (STREAM_DATA(s), bytes4, 1);
  946:   
  947:   asstr = aspath_str2aspath (sp->shouldbe);
  948:   
  949:   asconfeddel = aspath_delete_confed_seq (aspath_dup (asinout));
  950:   
  951:   printf ("got: %s\n", aspath_print(as));
  952:   
  953:   /* the parsed path should match the specified 'shouldbe' string.
  954:    * We should pass the "eat our own dog food" test, be able to output
  955:    * this path and then input it again. Ie the path resulting from:
  956:    *
  957:    *   aspath_parse(aspath_put(as)) 
  958:    *
  959:    * should:
  960:    *
  961:    * - also match the specified 'shouldbe' value
  962:    * - hash to same value as original path
  963:    * - have same hops and confed counts as original, and as the
  964:    *   the specified counts
  965:    *
  966:    * aspath_str2aspath() and shouldbe should match
  967:    *
  968:    * We do the same for:
  969:    *
  970:    *   aspath_parse(aspath_put(as,USE32BIT))
  971:    *
  972:    * Confederation related tests: 
  973:    * - aspath_delete_confed_seq(aspath) should match shouldbe_confed
  974:    * - aspath_delete_confed_seq should be idempotent.
  975:    */
  976:   if (strcmp(aspath_print (as), sp->shouldbe)
  977:          /* hash validation */
  978:       || (aspath_key_make (as) != aspath_key_make (asinout))
  979:          /* by string */
  980:       || strcmp(aspath_print (asinout), sp->shouldbe)
  981:          /* By 4-byte parsing */
  982:       || strcmp(aspath_print (as4), sp->shouldbe)
  983:          /* by various path counts */
  984:       || (aspath_count_hops (as) != sp->hops)
  985:       || (aspath_count_confeds (as) != sp->confeds)
  986:       || (aspath_count_hops (asinout) != sp->hops)
  987:       || (aspath_count_confeds (asinout) != sp->confeds))
  988:     {
  989:       failed++;
  990:       fails++;
  991:       printf ("shouldbe:\n%s\n", sp->shouldbe);
  992:       printf ("as4:\n%s\n", aspath_print (as4));
  993:       printf ("hash keys: in: %d out->in: %d\n", 
  994:               aspath_key_make (as), aspath_key_make (asinout));
  995:       printf ("hops: %d, counted %d %d\n", sp->hops, 
  996:               aspath_count_hops (as),
  997:               aspath_count_hops (asinout) );
  998:       printf ("confeds: %d, counted %d %d\n", sp->confeds,
  999:               aspath_count_confeds (as),
 1000:               aspath_count_confeds (asinout));
 1001:       printf ("out->in:\n%s\nbytes: ", aspath_print(asinout));
 1002:       printbytes (out, bytes);
 1003:     }
 1004:          /* basic confed related tests */
 1005:   if ((aspath_print (asconfeddel) == NULL 
 1006:           && sp->shouldbe_delete_confed != NULL)
 1007:       || (aspath_print (asconfeddel) != NULL 
 1008:           && sp->shouldbe_delete_confed == NULL)
 1009:       || strcmp(aspath_print (asconfeddel), sp->shouldbe_delete_confed)
 1010:          /* delete_confed_seq should be idempotent */
 1011:       || (aspath_key_make (asconfeddel) 
 1012:           != aspath_key_make (aspath_delete_confed_seq (asconfeddel))))
 1013:     {
 1014:       failed++;
 1015:       fails++;
 1016:       printf ("confed_del: %s\n", aspath_print (asconfeddel));
 1017:       printf ("should be: %s\n", sp->shouldbe_delete_confed);
 1018:     }
 1019:       /* aspath_str2aspath test */
 1020:   if ((aspath_print (asstr) == NULL && sp->shouldbe != NULL)
 1021:       || (aspath_print (asstr) != NULL && sp->shouldbe == NULL)
 1022:       || strcmp(aspath_print (asstr), sp->shouldbe))
 1023:     {
 1024:       failed++;
 1025:       fails++;
 1026:       printf ("asstr: %s\n", aspath_print (asstr));
 1027:     }
 1028:   
 1029:     /* loop, private and first as checks */
 1030:   if ((sp->does_loop && aspath_loop_check (as, sp->does_loop) == 0)
 1031:       || (sp->doesnt_loop && aspath_loop_check (as, sp->doesnt_loop) != 0)
 1032:       || (aspath_private_as_check (as) != sp->private_as)
 1033:       || (aspath_firstas_check (as,sp->first)
 1034:           && sp->first == 0))
 1035:     {
 1036:       failed++;
 1037:       fails++;
 1038:       printf ("firstas: %d,  got %d\n", sp->first,
 1039:               aspath_firstas_check (as,sp->first));
 1040:       printf ("loop does: %d %d, doesnt: %d %d\n",
 1041:               sp->does_loop, aspath_loop_check (as, sp->does_loop),
 1042:               sp->doesnt_loop, aspath_loop_check (as, sp->doesnt_loop));
 1043:       printf ("private check: %d %d\n", sp->private_as,
 1044:               aspath_private_as_check (as));
 1045:     }
 1046:   aspath_unintern (&asinout);
 1047:   aspath_unintern (&as4);
 1048:   
 1049:   aspath_free (asconfeddel);
 1050:   aspath_free (asstr);
 1051:   stream_reset (s);
 1052:   
 1053:   return fails;
 1054: }
 1055: 
 1056: static void
 1057: empty_get_test ()
 1058: {
 1059:   struct aspath *as = aspath_empty_get ();
 1060:   struct test_spec sp = { "", "", 0, 0, 0, 0, 0, 0 };
 1061: 
 1062:   printf ("empty_get_test, as: %s\n",aspath_print (as));
 1063:   if (!validate (as, &sp))
 1064:     printf ("%s\n", OK);
 1065:   else
 1066:     printf ("%s!\n", FAILED);
 1067:   
 1068:   printf ("\n");
 1069:   
 1070:   aspath_free (as);
 1071: }
 1072: 
 1073: /* basic parsing test */
 1074: static void
 1075: parse_test (struct test_segment *t)
 1076: {
 1077:   struct aspath *asp;
 1078:   
 1079:   printf ("%s: %s\n", t->name, t->desc);
 1080: 
 1081:   asp = make_aspath (t->asdata, t->len, 0);
 1082:   
 1083:   printf ("aspath: %s\nvalidating...:\n", aspath_print (asp));
 1084: 
 1085:   if (!validate (asp, &t->sp))
 1086:     printf (OK "\n");
 1087:   else
 1088:     printf (FAILED "\n");
 1089:   
 1090:   printf ("\n");
 1091:   
 1092:   if (asp)
 1093:     aspath_unintern (&asp);
 1094: }
 1095: 
 1096: /* prepend testing */
 1097: static void
 1098: prepend_test (struct tests *t)
 1099: {
 1100:   struct aspath *asp1, *asp2, *ascratch;
 1101:   
 1102:   printf ("prepend %s: %s\n", t->test1->name, t->test1->desc);
 1103:   printf ("to %s: %s\n", t->test2->name, t->test2->desc);
 1104:   
 1105:   asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
 1106:   asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
 1107:   
 1108:   ascratch = aspath_dup (asp2);
 1109:   aspath_unintern (&asp2);
 1110:   
 1111:   asp2 = aspath_prepend (asp1, ascratch);
 1112:   
 1113:   printf ("aspath: %s\n", aspath_print (asp2));
 1114:   
 1115:   if (!validate (asp2, &t->sp))
 1116:     printf ("%s\n", OK);
 1117:   else
 1118:     printf ("%s!\n", FAILED);
 1119:   
 1120:   printf ("\n");
 1121:   aspath_unintern (&asp1);
 1122:   aspath_free (asp2);
 1123: }
 1124: 
 1125: /* empty-prepend testing */
 1126: static void
 1127: empty_prepend_test (struct test_segment *t)
 1128: {
 1129:   struct aspath *asp1, *asp2, *ascratch;
 1130:   
 1131:   printf ("empty prepend %s: %s\n", t->name, t->desc);
 1132:   
 1133:   asp1 = make_aspath (t->asdata, t->len, 0);
 1134:   asp2 = aspath_empty ();
 1135:   
 1136:   ascratch = aspath_dup (asp2);
 1137:   aspath_unintern (&asp2);
 1138:   
 1139:   asp2 = aspath_prepend (asp1, ascratch);
 1140:   
 1141:   printf ("aspath: %s\n", aspath_print (asp2));
 1142:   
 1143:   if (!validate (asp2, &t->sp))
 1144:     printf (OK "\n");
 1145:   else
 1146:     printf (FAILED "!\n");
 1147:   
 1148:   printf ("\n");
 1149:   if (asp1)
 1150:     aspath_unintern (&asp1);
 1151:   aspath_free (asp2);
 1152: }
 1153: 
 1154: /* as2+as4 reconciliation testing */
 1155: static void
 1156: as4_reconcile_test (struct tests *t)
 1157: {
 1158:   struct aspath *asp1, *asp2, *ascratch;
 1159:   
 1160:   printf ("reconciling %s:\n  %s\n", t->test1->name, t->test1->desc);
 1161:   printf ("with %s:\n  %s\n", t->test2->name, t->test2->desc);
 1162:   
 1163:   asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
 1164:   asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
 1165:   
 1166:   ascratch = aspath_reconcile_as4 (asp1, asp2);
 1167:   
 1168:   if (!validate (ascratch, &t->sp))
 1169:     printf (OK "\n");
 1170:   else
 1171:     printf (FAILED "!\n");
 1172:   
 1173:   printf ("\n");
 1174:   aspath_unintern (&asp1);
 1175:   aspath_unintern (&asp2);
 1176:   aspath_free (ascratch);
 1177: }
 1178: 
 1179: 
 1180: /* aggregation testing */
 1181: static void
 1182: aggregate_test (struct tests *t)
 1183: {
 1184:   struct aspath *asp1, *asp2, *ascratch;
 1185:   
 1186:   printf ("aggregate %s: %s\n", t->test1->name, t->test1->desc);
 1187:   printf ("with %s: %s\n", t->test2->name, t->test2->desc);
 1188:   
 1189:   asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
 1190:   asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
 1191:   
 1192:   ascratch = aspath_aggregate (asp1, asp2);
 1193:   
 1194:   if (!validate (ascratch, &t->sp))
 1195:     printf (OK "\n");
 1196:   else
 1197:     printf (FAILED "!\n");
 1198:   
 1199:   printf ("\n");
 1200:   aspath_unintern (&asp1);
 1201:   aspath_unintern (&asp2);
 1202:   aspath_free (ascratch);
 1203: /*  aspath_unintern (ascratch);*/
 1204: }
 1205: 
 1206: /* cmp_left tests  */
 1207: static void
 1208: cmp_test ()
 1209: {
 1210:   unsigned int i;
 1211: #define CMP_TESTS_MAX \
 1212:   (sizeof(left_compare) / sizeof (struct compare_tests))
 1213: 
 1214:   for (i = 0; i < CMP_TESTS_MAX; i++)
 1215:     {
 1216:       struct test_segment *t1 = &test_segments[left_compare[i].test_index1];
 1217:       struct test_segment *t2 = &test_segments[left_compare[i].test_index2];
 1218:       struct aspath *asp1, *asp2;
 1219:       
 1220:       printf ("left cmp %s: %s\n", t1->name, t1->desc);
 1221:       printf ("and %s: %s\n", t2->name, t2->desc);
 1222:       
 1223:       asp1 = make_aspath (t1->asdata, t1->len, 0);
 1224:       asp2 = make_aspath (t2->asdata, t2->len, 0);
 1225:       
 1226:       if (aspath_cmp_left (asp1, asp2) != left_compare[i].shouldbe_cmp
 1227:           || aspath_cmp_left (asp2, asp1) != left_compare[i].shouldbe_cmp
 1228:           || aspath_cmp_left_confed (asp1, asp2) 
 1229:                != left_compare[i].shouldbe_confed
 1230:           || aspath_cmp_left_confed (asp2, asp1) 
 1231:                != left_compare[i].shouldbe_confed)
 1232:         {
 1233:           failed++;
 1234:           printf (FAILED "\n");
 1235:           printf ("result should be: cmp: %d, confed: %d\n", 
 1236:                   left_compare[i].shouldbe_cmp,
 1237:                   left_compare[i].shouldbe_confed);
 1238:           printf ("got: cmp %d, cmp_confed: %d\n",
 1239:                   aspath_cmp_left (asp1, asp2),
 1240:                   aspath_cmp_left_confed (asp1, asp2));
 1241:           printf("path1: %s\npath2: %s\n", aspath_print (asp1),
 1242:                  aspath_print (asp2));
 1243:         }
 1244:       else
 1245:         printf (OK "\n");
 1246:       
 1247:       printf ("\n");
 1248:       aspath_unintern (&asp1);
 1249:       aspath_unintern (&asp2);
 1250:     }
 1251: }
 1252: 
 1253: static int
 1254: handle_attr_test (struct aspath_tests *t)
 1255: {
 1256:   struct bgp bgp = { 0 }; 
 1257:   struct peer peer = { 0 };
 1258:   struct attr attr = { 0 };  
 1259:   int ret;
 1260:   int initfail = failed;
 1261:   struct aspath *asp;
 1262:   size_t datalen;
 1263:   
 1264:   asp = make_aspath (t->segment->asdata, t->segment->len, 0);
 1265:     
 1266:   peer.ibuf = stream_new (BGP_MAX_PACKET_SIZE);
 1267:   peer.obuf = stream_fifo_new ();
 1268:   peer.bgp = &bgp;
 1269:   peer.host = (char *)"none";
 1270:   peer.fd = -1;
 1271:   peer.cap = t->cap;
 1272:   
 1273:   stream_write (peer.ibuf, t->attrheader, t->len);
 1274:   datalen = aspath_put (peer.ibuf, asp, t->as4 == AS4_DATA);
 1275:   if (t->old_segment)
 1276:     {
 1277:       char dummyaspath[] = { BGP_ATTR_FLAG_TRANS, BGP_ATTR_AS_PATH,
 1278:                              t->old_segment->len };
 1279:       stream_write (peer.ibuf, dummyaspath, sizeof (dummyaspath));
 1280:       stream_write (peer.ibuf, t->old_segment->asdata, t->old_segment->len);
 1281:       datalen += sizeof (dummyaspath) + t->old_segment->len;
 1282:     }
 1283:   
 1284:   ret = bgp_attr_parse (&peer, &attr, t->len + datalen, NULL, NULL);
 1285:   
 1286:   if (ret != t->result)
 1287:     {
 1288:       printf ("bgp_attr_parse returned %d, expected %d\n", ret, t->result);
 1289:       printf ("datalen %zd\n", datalen);
 1290:       failed++;
 1291:     }
 1292:   if (ret != 0)
 1293:     goto out;
 1294:   
 1295:   if (t->shouldbe && attr.aspath == NULL)
 1296:     {
 1297:       printf ("aspath is NULL, but should be: %s\n", t->shouldbe);
 1298:       failed++;
 1299:     }
 1300:   if (t->shouldbe && attr.aspath && strcmp (attr.aspath->str, t->shouldbe))
 1301:     {
 1302:       printf ("attr str and 'shouldbe' mismatched!\n"
 1303:               "attr str:  %s\n"
 1304:               "shouldbe:  %s\n",
 1305:               attr.aspath->str, t->shouldbe);
 1306:       failed++;
 1307:     }
 1308:   if (!t->shouldbe && attr.aspath)
 1309:     {
 1310:       printf ("aspath should be NULL, but is: %s\n", attr.aspath->str);
 1311:       failed++;
 1312:     }
 1313: 
 1314: out:
 1315:   if (attr.aspath)
 1316:     aspath_unintern (&attr.aspath);
 1317:   if (asp)
 1318:     aspath_unintern (&asp);
 1319:   return failed - initfail;
 1320: }
 1321: 
 1322: static void
 1323: attr_test (struct aspath_tests *t)
 1324: {
 1325:     printf ("%s\n", t->desc);
 1326:     printf ("%s\n\n", handle_attr_test (t) ? FAILED : OK);  
 1327: }
 1328: 
 1329: int
 1330: main (void)
 1331: {
 1332:   int i = 0;
 1333:   bgp_master_init ();
 1334:   master = bm->master;
 1335:   bgp_option_set (BGP_OPT_NO_LISTEN);
 1336:   bgp_attr_init ();
 1337:   
 1338:   while (test_segments[i].name)
 1339:     {
 1340:       printf ("test %u\n", i);
 1341:       parse_test (&test_segments[i]);
 1342:       empty_prepend_test (&test_segments[i++]);
 1343:     }
 1344:   
 1345:   i = 0;
 1346:   while (prepend_tests[i].test1)
 1347:     {
 1348:       printf ("prepend test %u\n", i);
 1349:       prepend_test (&prepend_tests[i++]);
 1350:     }
 1351:   
 1352:   i = 0;
 1353:   while (aggregate_tests[i].test1)
 1354:     {
 1355:       printf ("aggregate test %u\n", i);
 1356:       aggregate_test (&aggregate_tests[i++]);
 1357:     }
 1358:   
 1359:   i = 0;
 1360:   
 1361:   while (reconcile_tests[i].test1)
 1362:     {
 1363:       printf ("reconcile test %u\n", i);
 1364:       as4_reconcile_test (&reconcile_tests[i++]);
 1365:     }
 1366:   
 1367:   i = 0;
 1368:   
 1369:   cmp_test();
 1370:   
 1371:   i = 0;
 1372:   
 1373:   empty_get_test();
 1374:   
 1375:   i = 0;
 1376:   
 1377:   while (aspath_tests[i].desc)
 1378:     {
 1379:       printf ("aspath_attr test %d\n", i);
 1380:       attr_test (&aspath_tests[i++]);
 1381:     }
 1382:   
 1383:   printf ("failures: %d\n", failed);
 1384:   printf ("aspath count: %ld\n", aspath_count());
 1385:   
 1386:   return (failed + aspath_count());
 1387: }

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