Revision fe9f1a6d proto/rip/packets.c

View differences:

proto/rip/packets.c
78 78
/* Internal representation of RTE block data */
79 79
struct rip_block
80 80
{
81
  ip_addr prefix;
82
  int pxlen;
81
  net_addr net;
83 82
  u32 metric;
84 83
  u16 tag;
85 84
  u16 no_af;
......
115 114
    struct rip_block_v2 *block = (void *) pos;
116 115
    block->family = rte->no_af ? 0 : htons(RIP_AF_IPV4);
117 116
    block->tag = htons(rte->tag);
118
    block->network = ip4_hton(ipa_to_ip4(rte->prefix));
119
    block->netmask = ip4_hton(ip4_mkmask(rte->pxlen));
117
    block->network = ip4_hton(net4_prefix(&rte->net));
118
    block->netmask = ip4_hton(ip4_mkmask(net4_pxlen(&rte->net)));
120 119
    block->next_hop = ip4_hton(ipa_to_ip4(rte->next_hop));
121 120
    block->metric = htonl(rte->metric);
122 121
  }
123 122
  else /* RIPng */
124 123
  {
125 124
    struct rip_block_ng *block = (void *) pos;
126
    block->prefix = ip6_hton(ipa_to_ip6(rte->prefix));
125
    block->prefix = ip6_hton(net6_prefix(&rte->net));
127 126
    block->tag = htons(rte->tag);
128
    block->pxlen = rte->pxlen;
127
    block->pxlen = net6_pxlen(&rte->net);
129 128
    block->metric = rte->metric;
130 129
  }
131 130
}
......
151 150
    if (block->family != (rte->no_af ? 0 : htons(RIP_AF_IPV4)))
152 151
      return 0;
153 152

  
154
    rte->prefix = ipa_from_ip4(ip4_ntoh(block->network));
155
    rte->pxlen = ip4_masklen(ip4_ntoh(block->netmask));
153
    uint pxlen = ip4_masklen(ip4_ntoh(block->netmask));
154
    net_fill_ip4(&rte->net, ip4_ntoh(block->network), pxlen);
156 155
    rte->metric = ntohl(block->metric);
157 156
    rte->tag = ntohs(block->tag);
158 157
    rte->next_hop = ipa_from_ip4(ip4_ntoh(block->next_hop));
......
171 170
      return 0;
172 171
    }
173 172

  
174
    rte->prefix = ipa_from_ip6(ip6_ntoh(block->prefix));
175
    rte->pxlen = block->pxlen;
173
    uint pxlen = (block->pxlen < IP6_MAX_PREFIX_LENGTH) ? block->pxlen : 255;
174
    net_fill_ip6(&rte->net, ip6_ntoh(block->prefix), pxlen);
176 175
    rte->metric = block->metric;
177 176
    rte->tag = ntohs(block->tag);
178 177
    /* rte->next_hop is deliberately kept unmodified */;
......
385 384
  if (!rip_get_block(p, pos, &b))
386 385
    return;
387 386

  
388
  /* Special case - zero prefix, infinity metric */
389
  if (ipa_nonzero(b.prefix) || b.pxlen || (b.metric != p->infinity))
387
  /* Special case - infinity metric, for RIPng also zero prefix */
388
  if ((b.metric != p->infinity) ||
389
      (rip_is_ng(p) && !net_zero_ip6((net_addr_ip6 *) &b.net)))
390 390
    return;
391 391

  
392 392
  /* We do nothing if TX is already active */
......
444 444
    }
445 445

  
446 446
    struct rip_block rte = {
447
      .prefix = en->n.prefix,
448
      .pxlen = en->n.pxlen,
449 447
      .metric = en->metric,
450 448
      .tag = en->tag
451 449
    };
452 450

  
451
    net_copy(&rte.net, en->n.addr);
452

  
453 453
    if (en->iface == ifa->iface)
454 454
      rte.next_hop = en->next_hop;
455 455

  
456 456
    if (rip_is_v2(p) && (ifa->cf->version == RIP_V1))
457 457
    {
458 458
      /* Skipping subnets (i.e. not hosts, classful networks or default route) */
459
      if (ip4_masklen(ip4_class_mask(ipa_to_ip4(en->n.prefix))) != en->n.pxlen)
459
      if (ip4_masklen(ip4_class_mask(net4_prefix(&rte.net))) != rte.net.pxlen)
460 460
	goto next_entry;
461 461

  
462 462
      rte.tag = 0;
463
      rte.pxlen = 0;
463
      rte.net.pxlen = 0;
464 464
      rte.next_hop = IPA_NONE;
465 465
    }
466 466

  
......
476 476
	goto next_entry;
477 477
    }
478 478

  
479
    // TRACE(D_PACKETS, "    %I/%d -> %I metric %d", rte.prefix, rte.pxlen, rte.next_hop, rte.metric);
479
    // TRACE(D_PACKETS, "    %N -> %I metric %d", &rte.net, rte.next_hop, rte.metric);
480 480

  
481 481
    /* RIPng next hop entry */
482 482
    if (rip_is_ng(p) && !ipa_equal(rte.next_hop, last_next_hop))
......
577 577
    if (!rip_get_block(p, pos, &rte))
578 578
      continue;
579 579

  
580
    int c = ipa_classify_net(rte.prefix);
581
    if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
582
      SKIP("invalid prefix");
583

  
584 580
    if (rip_is_v2(p) && (pkt->version == RIP_V1))
585 581
    {
586
      if (ifa->cf->check_zero && (rte.tag || rte.pxlen || ipa_nonzero(rte.next_hop)))
582
      if (ifa->cf->check_zero && (rte.tag || rte.net.pxlen || ipa_nonzero(rte.next_hop)))
587 583
	SKIP("RIPv1 reserved field is nonzero");
588 584

  
589 585
      rte.tag = 0;
590
      rte.pxlen = ip4_masklen(ip4_class_mask(ipa_to_ip4(rte.prefix)));
586
      rte.net.pxlen = ip4_masklen(ip4_class_mask(net4_prefix(&rte.net)));
591 587
      rte.next_hop = IPA_NONE;
592 588
    }
593 589

  
594
    if ((rte.pxlen < 0) || (rte.pxlen > MAX_PREFIX_LENGTH))
590
    if (rte.net.pxlen == 255)
595 591
      SKIP("invalid prefix length");
596 592

  
593
    net_normalize(&rte.net);
594

  
595
    int c = net_classify(&rte.net);
596
    if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
597
      SKIP("invalid prefix");
598

  
597 599
    if (rte.metric > p->infinity)
598 600
      SKIP("invalid metric");
599 601

  
......
604 606
	rte.next_hop = IPA_NONE;
605 607
    }
606 608

  
607
    // TRACE(D_PACKETS, "    %I/%d -> %I metric %d", rte.prefix, rte.pxlen, rte.next_hop, rte.metric);
609
    // TRACE(D_PACKETS, "    %N -> %I metric %d", &rte.net.n, rte.next_hop, rte.metric);
608 610

  
609 611
    rte.metric += ifa->cf->metric;
610 612

  
......
618 620
	.expires = now + ifa->cf->timeout_time
619 621
      };
620 622

  
621
      rip_update_rte(p, &rte.prefix, rte.pxlen, &new);
623
      rip_update_rte(p, &rte.net, &new);
622 624
    }
623 625
    else
624
      rip_withdraw_rte(p, &rte.prefix, rte.pxlen, from);
626
      rip_withdraw_rte(p, &rte.net, from);
625 627

  
626 628
    continue;
627 629

  
628 630
  skip:
629
    LOG_RTE("Ignoring route %I/%d received from %I - %s",
630
	    rte.prefix, rte.pxlen, from->nbr->addr, err_dsc);
631
    LOG_RTE("Ignoring route %N received from %I - %s",
632
	    &rte.net, from->nbr->addr, err_dsc);
631 633
  }
632 634
}
633 635

  

Also available in: Unified diff