Revision 061ab802

View differences:

lib/ipv6.c
136 136
  return 0;
137 137
}
138 138

  
139
/* From Linux include/net/ipv6.h */
140
#define NEXTHDR_HOP             0       /* Hop-by-hop option header. */
141
#define NEXTHDR_ROUTING         43      /* Routing header. */
142
#define NEXTHDR_FRAGMENT        44      /* Fragmentation/reassembly header. */
143
#define NEXTHDR_DEST            60      /* Destination options header. */
144
#define NEXTHDR_NONE            59      /* No next header */
145

  
146
#define NEXTHDR_ESP             50      /* Encapsulating security payload. */
147
#define NEXTHDR_AUTH            51      /* Authentication header. */
148

  
149

  
150
byte *
151
ipv6_skip_header(byte *pkt, int *len)
152
{
153
  int l = *len;
154
  int q;
155
  u8 nh;
156

  
157
  if (l < 40 || (*pkt & 0xf0) != 0x60)
158
    return NULL;
159

  
160
  /* Skip IPv6 header */
161
  nh = pkt[6];
162
  pkt += 40;
163

  
164
  while ()
165
    {
166
      switch (nw)
167
	{
168
	case NEXTHDR_FRAGMENT:
169

  
170
	case NEXTHDR_HOP:
171
	case NEXTHDR_ROUTING:
172
	case NEXTHDR_DEST:
173

  
174
	case NEXTHDR_AUTH:
175
	  break;
176

  
177
	case NEXTHDR_NONE:
178
	  return NULL;
179

  
180
	default:
181
	  return pkt;
182
	}
183
    }
184

  
185
  q = (*pkt & 0x0f) * 4;
186
  if (q > l)
187
    return NULL;
188
  *len -= q;
189
  return pkt + q;
190
}
191

  
192

  
193 139
/*
194 140
 *  Conversion of IPv6 address to presentation format and vice versa.
195 141
 *  Heavily inspired by routines written by Paul Vixie for the BIND project
lib/ipv6.h
69 69
#define ipa_getbit(x, y) ipv6_getbit(x, y)
70 70
#define ipa_absolutize(x,y) ipv6_absolutize(x,y)
71 71

  
72
/* In IPv6, SOCK_RAW does not return packet header */
73
#define ip_skip_header(x, y) x
74

  
72 75
ip_addr ipv6_mkmask(unsigned);
73 76
unsigned ipv6_mklen(ip_addr *);
74 77
int ipv6_classify(ip_addr *);
nest/neighbor.c
103 103
neighbor *
104 104
neigh_find(struct proto *p, ip_addr *a, unsigned flags)
105 105
{
106
  return neigh_find2(p, a, NULL, flags);
107
}
108

  
109
neighbor *
110
neigh_find2(struct proto *p, ip_addr *a, unsigned flags)
111
{
106 112
  neighbor *n;
107 113
  int class, scope = SCOPE_HOST;
108 114
  unsigned int h = neigh_hash(p, a);
proto/ospf/iface.c
67 67
  ipsk = sk_new(p->pool);
68 68
  ipsk->type = SK_IP;
69 69
  ipsk->dport = OSPF_PROTO;
70

  
71
#ifdef OSPFv2
70 72
  ipsk->saddr = ifa->iface->addr->ip;
73
#else /* OSPFv3 */
74
  ipsk->saddr = ifa->lladdr;
75
#endif
76

  
71 77
  ipsk->tos = IP_PREC_INTERNET_CONTROL;
72 78
  ipsk->ttl = 1;
73 79
  if (ifa->type == OSPF_IT_VLINK)
......
135 141
	    ifa->dr_sk->type = SK_IP_MC;
136 142
	    ifa->dr_sk->sport = 0;
137 143
	    ifa->dr_sk->dport = OSPF_PROTO;
144

  
145
#ifdef OSPFv2
138 146
	    ifa->dr_sk->saddr = AllDRouters;
147
#else /* OSPFv3 */
148
	    ifa->dr_sk->saddr = ifa->lladdr;
149
#endif
150

  
139 151
	    ifa->dr_sk->daddr = AllDRouters;
140 152
	    ifa->dr_sk->tos = IP_PREC_INTERNET_CONTROL;
141 153
	    ifa->dr_sk->ttl = 1;
......
308 320
  mcsk->type = SK_IP_MC;
309 321
  mcsk->sport = 0;
310 322
  mcsk->dport = OSPF_PROTO;
311
  mcsk->saddr = AllSPFRouters;
323

  
324
#ifdef OSPFv2
325
  mcsk->saddr = AllDRouters;
326
#else /* OSPFv3 */
327
  mcsk->saddr = ifa->lladdr;
328
#endif
329

  
312 330
  mcsk->daddr = AllSPFRouters;
313 331
  mcsk->tos = IP_PREC_INTERNET_CONTROL;
314 332
  mcsk->ttl = 1;
proto/ospf/lsalib.c
99 99
#ifdef OSPFv2
100 100
  n->options = h->options;
101 101
#endif
102
  n->type = h->type;
102
  n->type = htont(h->type);
103 103
  n->id = htonl(h->id);
104 104
  n->rt = htonl(h->rt);
105 105
  n->sn = htonl(h->sn);
......
114 114
#ifdef OSPFv2
115 115
  h->options = n->options;
116 116
#endif
117
  h->type = n->type;
117
  h->type = ntoht(n->type);
118 118
  h->id = ntohl(n->id);
119 119
  h->rt = ntohl(n->rt);
120 120
  h->sn = ntohl(n->sn);
......
143 143
      nrt->links = htons(hrt->links);
144 144
      links = hrt->links;
145 145
#else /* OSPFv3 */
146
      hrt->options = htonl(nrt->options);
146
      nrt->options = htonl(hrt->options);
147 147
      links = (len - sizeof(struct ospf_lsa_rt)) /
148 148
	sizeof(struct ospf_lsa_rt_link);
149 149
#endif
......
173 173
  case LSA_T_SUM_NET:
174 174
  case LSA_T_SUM_RT:
175 175
  case LSA_T_EXT:
176
#ifdef OSPFv3
177
  case LSA_T_LINK:
178
  case LSA_T_PREFIX:
179
#endif
176 180
    {
177 181
      u32 *hid, *nid;
178 182

  
......
241 245
  case LSA_T_SUM_NET:
242 246
  case LSA_T_SUM_RT:
243 247
  case LSA_T_EXT:
248
#ifdef OSPFv3
249
  case LSA_T_LINK:
250
  case LSA_T_PREFIX:
251
#endif
244 252
    {
245 253
      u32 *hid, *nid;
246 254

  
......
258 266
  }
259 267
};
260 268

  
269
void
270
buf_dump(const char *hdr, const byte *buf, int blen)
271
{
272
  char b2[1024];
273
  char *bp;
274
  int first = 1;
275
  int i;
276

  
277
  const char *lhdr = hdr;
278

  
279
  bp = b2;
280
  for(i = 0; i < blen; i++)
281
    {
282
      if ((i > 0) && ((i % 16) == 0))
283
	{
284
	      *bp = 0;
285
	      log(L_WARN "%s\t%s", lhdr, b2);
286
	      lhdr = "";
287
	      bp = b2;
288
	}
289

  
290
      bp += snprintf(bp, 1022, "%02x ", buf[i]);
291

  
292
    }
293

  
294
  *bp = 0;
295
  log(L_WARN "%s\t%s", lhdr, b2);
296
}
297

  
261 298
#define MODX 4102		/* larges signed value without overflow */
262 299

  
263 300
/* Fletcher Checksum -- Refer to RFC1008. */
......
268 305
void
269 306
lsasum_calculate(struct ospf_lsa_header *h, void *body)
270 307
{
271
  u16 length;
272

  
273
  length = h->length;
308
  u16 length = h->length;
309
  u16 type = h->type;
274 310

  
311
  log(L_WARN "Checksum %R %R %d start (len %d)", h->id, h->rt, h->type, length);
275 312
  htonlsah(h, h);
276
  htonlsab(body, body, h->type, length - sizeof(struct ospf_lsa_header));
313

  
314
  htonlsab(body, body, type, length - sizeof(struct ospf_lsa_header));
315

  
316
  char buf[1024];
317
  memcpy(buf, h, sizeof(struct ospf_lsa_header));
318
  memcpy(buf + sizeof(struct ospf_lsa_header), body, length - sizeof(struct ospf_lsa_header));
319
  buf_dump("CALC", buf, length);
277 320

  
278 321
  (void) lsasum_check(h, body);
279 322

  
323
  log(L_WARN "Checksum result %4x", h->checksum);
324

  
280 325
  ntohlsah(h, h);
281
  ntohlsab(body, body, h->type, length - sizeof(struct ospf_lsa_header));
326
  ntohlsab(body, body, type, length - sizeof(struct ospf_lsa_header));
282 327
}
283 328

  
284 329
/*
......
294 339
  u16 length;
295 340

  
296 341
  b = body;
297
  sp = (char *) &h;
342
  sp = (char *) h;
298 343
  sp += 2; /* Skip Age field */
299 344
  length = ntohs(h->length) - 2;
300 345
  h->checksum = 0;
proto/ospf/lsupd.c
78 78

  
79 79
#else /* OSPFv3 */
80 80

  
81
static int
82
unknown_lsa_type(struct ospf_lsa_header *lsa)
83
{
84
  switch (lsa->type)
85
    {
86
    case LSA_T_RT:
87
    case LSA_T_NET:
88
    case LSA_T_SUM_NET:
89
    case LSA_T_SUM_RT:
90
    case LSA_T_EXT:
91
    case LSA_T_LINK:
92
    case LSA_T_PREFIX:
93
      return 0;
94

  
95
    default:
96
      return 1;
97
    }
98
}
99

  
81 100
int
82 101
ospf_lsa_flooding_allowed(struct ospf_lsa_header *lsa, u32 domain, struct ospf_iface *ifa)
83 102
{    
84 103
  u32 scope = LSA_SCOPE(lsa);
85 104

  
86 105
  /* 4.5.2 (Case 2) */
87
  if (unknown_type(lsa) && !(lsa->type & LSA_UBIT))
106
  if (unknown_lsa_type(lsa) && !(lsa->type & LSA_UBIT))
88 107
    scope = LSA_SCOPE_LINK;
89 108

  
90 109
  switch (scope)
......
444 463

  
445 464
    /* pg 143 (1) */
446 465
    chsum = lsa->checksum;
466
    log(L_WARN "Checking rcv %R %R %d (len %d)", ntohl(lsa->id), ntohl(lsa->rt), ntoht(lsa->type), ntohs(lsa->length));
467
    buf_dump("RCV", lsa, ntohs(lsa->length));
447 468
    if (chsum != lsasum_check(lsa, NULL))
448 469
    {
449
      log(L_WARN "Received bad lsa checksum from %I", n->ip);
470
      log(L_WARN "Received bad lsa checksum from %I: %x %x", n->ip, chsum, lsa->checksum);
450 471
      continue;
451 472
    }
452 473

  
proto/ospf/neighbor.c
451 451
  me.state = NEIGHBOR_2WAY;
452 452
  me.rid = myid;
453 453
  me.priority = ifa->priority;
454
  me.ip = ifa->iface->addr->ip;
455 454

  
456 455
#ifdef OSPFv2
456
  me.ip = ifa->iface->addr->ip;
457 457
  me.dr = ipa_to_u32(ifa->drip);
458 458
  me.bdr = ipa_to_u32(ifa->bdrip);
459 459
#else /* OSPFv3 */
460
  me.ip = ifa->lladdr;
460 461
  me.dr = ifa->drid;
461 462
  me.bdr = ifa->bdrid;
462 463
  me.iface_id = ifa->iface->index;
proto/ospf/ospf.h
424 424

  
425 425
#define LSA_EXT_EBIT 0x80000000
426 426

  
427
/* Endianity swap for lsa->type */
428
#define ntoht(x) x
429
#define htont(x) x
430

  
427 431

  
428 432
#else  /* OSPFv3 */
429 433

  
......
488 492
#define LSA_EXT_FBIT 0x2000000
489 493
#define LSA_EXT_TBIT 0x1000000
490 494

  
495
/* Endianity swap for lsa->type */
496
#define ntoht(x) ntohs(x)
497
#define htont(x) htons(x)
498

  
491 499
#endif
492 500

  
493 501
#define METRIC_MASK  0x00FFFFFF
proto/ospf/rt.c
312 312
	  nf.ar = act;
313 313
	  nf.nh = act->nh;
314 314
	  nf.ifa = act->nhi;
315
	  ri_install(po, ipa_from_rid(act->lsa.rt), 32, ORT_ROUTER, &nf, NULL);
315
	  ri_install(po, ipa_from_rid(act->lsa.rt), MAX_PREFIX_LENGTH, ORT_ROUTER, &nf, NULL);
316 316
	}
317 317

  
318 318
      rr = (struct ospf_lsa_rt_link *) (rt + 1);
......
582 582
#endif
583 583

  
584 584
      ip = ipa_from_rid(dst_rid);
585
      pxlen = 32;
585
      pxlen = MAX_PREFIX_LENGTH;
586 586
      metric = ls->metric & METRIC_MASK;
587 587
      options |= ORTA_ASBR;
588 588
      type = ORT_ROUTER;
......
595 595

  
596 596
    abrip = ipa_from_rid(en->lsa.rt);
597 597

  
598
    abr = fib_find(&oa->rtr, &abrip, 32);
598
    abr = fib_find(&oa->rtr, &abrip, MAX_PREFIX_LENGTH);
599 599
    if (!abr) continue;
600 600

  
601 601
    nf.type = re->n.type;
......
691 691
#endif
692 692

  
693 693
      ip = ipa_from_rid(dst_rid);
694
      pxlen = 32;
694
      pxlen = MAX_PREFIX_LENGTH;
695 695
      metric = ls->metric & METRIC_MASK;
696 696
      options |= ORTA_ASBR;
697 697
      type = ORT_ROUTER;
......
703 703

  
704 704
    /* Page 169 (4) */
705 705
    abrip = ipa_from_rid(en->lsa.rt);
706
    if (!(abr = (ort *) fib_find(&oa->rtr, &abrip, 32))) continue;
706
    if (!(abr = (ort *) fib_find(&oa->rtr, &abrip, MAX_PREFIX_LENGTH))) continue;
707 707
    if (abr->n.metric1 == LSINFINITY) continue;
708 708
    if (!(abr->n.options & ORTA_ABR)) continue;
709 709

  
......
891 891
    nf1 = NULL;
892 892
    WALK_LIST(atmp, po->area_list)
893 893
    {
894
      nfh = fib_find(&atmp->rtr, &rtid, 32);
894
      nfh = fib_find(&atmp->rtr, &rtid, MAX_PREFIX_LENGTH);
895 895
      if (nfh == NULL) continue;
896 896
      if (nf1 == NULL) nf1 = nfh;
897 897
      else if (ri_better(po, &nfh->n, NULL, &nf1->n, NULL, po->rfc1583)) nf1 = nfh;
......
915 915
    }
916 916
    else
917 917
    {
918
      nf2 = fib_route(&po->rtf, rt_fwaddr, 32);
918
      nf2 = fib_route(&po->rtf, rt_fwaddr, MAX_PREFIX_LENGTH);
919 919

  
920 920
      if (!nf2)
921 921
      {
......
923 923
	continue;
924 924
      }
925 925

  
926

  
927 926
      if ((nn = neigh_find(p, &rt_fwaddr, 0)) != NULL)
928 927
      {
929 928
	nh = rt_fwaddr;
......
1179 1178
        int found = 0;
1180 1179
        struct ospf_iface *ifa;
1181 1180
        struct top_hash_entry *en;
1182
        OSPF_TRACE(D_EVENTS, "Trying to find correct next hop");
1181
        OSPF_TRACE(D_EVENTS, "Trying to find correct next hop %I/%d via %I", nf->fn.prefix, nf->fn.pxlen, nf->n.nh);
1183 1182
        WALK_LIST(ifa, po->iface_list)
1184 1183
        {
1185 1184
          if ((ifa->type == OSPF_IT_VLINK) && ipa_equal(ifa->vip, nf->n.nh))
proto/ospf/topology.c
22 22

  
23 23
void originate_prefix_rt_lsa(struct ospf_area *oa);
24 24
void originate_prefix_net_lsa(struct ospf_iface *ifa);
25
void flush_prefix_net_lsa(struct ospf_iface *ifa);
25 26

  
26 27
#ifdef OSPFv2
27 28
#define ipa_to_rid(x) _I(x)
......
557 558
  ifa->net_lsa->lsa.age = LSA_MAXAGE;
558 559
  lsasum_calculate(&ifa->net_lsa->lsa, ifa->net_lsa->lsa_body);
559 560
  ospf_lsupd_flood(po, NULL, NULL, &ifa->net_lsa->lsa, dom, 0);
560

  
561

  
562 561
  flush_lsa(ifa->net_lsa, po);
563 562
  ifa->net_lsa = NULL;
564 563
}
......
1215 1214
  ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1);
1216 1215
}
1217 1216

  
1217
void
1218
flush_prefix_net_lsa(struct ospf_iface *ifa)
1219
{
1220
  struct proto_ospf *po = ifa->oa->po;
1221
  struct proto *p = &po->proto;
1222
  struct top_hash_entry *en = ifa->pxn_lsa;
1223
  u32 dom = ifa->oa->areaid;
1224

  
1225
  if (en == NULL)
1226
    return;
1227

  
1228
  OSPF_TRACE(D_EVENTS, "Flushing Net Prefix lsa for iface \"%s\".",
1229
	     ifa->iface->name);
1230
  en->lsa.sn += 1;
1231
  en->lsa.age = LSA_MAXAGE;
1232
  lsasum_calculate(&en->lsa, en->lsa_body);
1233
  ospf_lsupd_flood(po, NULL, NULL, &en->lsa, dom, 0);
1234
  flush_lsa(en, po);
1235
  ifa->pxn_lsa = NULL;
1236
}
1237

  
1238

  
1218 1239
#endif
1219 1240

  
1220 1241

  
sysdep/unix/io.c
636 636
  set_inaddr(&sa->sin6_addr, a);
637 637
}
638 638

  
639
static inline void
640
fill_in_sockifa(sockaddr *sa, struct iface *ifa)
641
{
642
  sa->sin6_scope_id = ifa ? ifa->index : 0;
643
}
644

  
639 645
void
640 646
get_sockaddr(struct sockaddr_in6 *sa, ip_addr *a, unsigned *port, int check)
641 647
{
......
661 667
  set_inaddr(&sa->sin_addr, a);
662 668
}
663 669

  
670
static inline void
671
fill_in_sockifa(sockaddr *sa, struct iface *ifa)
672
{
673
}
674

  
664 675
void
665 676
get_sockaddr(struct sockaddr_in *sa, ip_addr *a, unsigned *port, int check)
666 677
{
......
874 885
    {
875 886
    case SK_UDP:
876 887
    case SK_IP:
888
#ifndef IPV6
877 889
      if (s->iface)			/* It's a broadcast socket */
878
#ifdef IPV6
879
	bug("IPv6 has no broadcasts");
880
#else
881 890
	if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) < 0)
882 891
	  ERR("SO_BROADCAST");
883 892
#endif
......
911 920
	    if (setsockopt(fd, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
912 921
	      ERR("IPV6_ADD_MEMBERSHIP");
913 922
	  }
914
#else
923
#else /* IPv4 */
915 924
	/* With IPv4 there are zillions of different socket interface variants. Ugh. */
916 925
	ASSERT(s->iface && s->iface->addr);
917 926
	if (err = sysio_mcast_join(s))
......
933 942
	    ERR("SO_REUSEADDR");
934 943
	}
935 944
      fill_in_sockaddr(&sa, s->saddr, port);
945
      fill_in_sockifa(&sa, s->iface);
936 946
#ifdef CONFIG_SKIP_MC_BIND
937 947
      if ((type != SK_UDP_MC) && (type != SK_IP_MC) &&
938 948
	  bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0)
......
1067 1077

  
1068 1078
	if (s->tbuf == s->tpos)
1069 1079
	  return 1;
1070
	fill_in_sockaddr(&sa, s->faddr, s->fport);
1071 1080

  
1081
	fill_in_sockaddr(&sa, s->faddr, s->fport);
1082
	fill_in_sockifa(&sa, s->iface);
1072 1083
	e = sendto(s->fd, s->tbuf, s->tpos - s->tbuf, 0, (struct sockaddr *) &sa, sizeof(sa));
1073 1084
	if (e < 0)
1074 1085
	  {

Also available in: Unified diff