Revision 4827b69f proto/bgp/packets.c

View differences:

proto/bgp/packets.c
234 234
{
235 235
  struct bgp_proto *p = conn->bgp;
236 236
  struct bgp_bucket *buck;
237
  int size, is_ll;
237
  int size;
238 238
  int remains = BGP_MAX_PACKET_LENGTH - BGP_HEADER_LENGTH - 4;
239 239
  byte *w, *tmp, *tstart;
240
  ip_addr ip, ip_ll;
240
  ip_addr *ipp, ip, ip_ll;
241 241
  ea_list *ea;
242 242
  eattr *nh;
243 243
  neighbor *n;
......
291 291
	  *tmp++ = 1;
292 292
	  nh = ea_find(buck->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
293 293
	  ASSERT(nh);
294
	  ip = *(ip_addr *) nh->u.ptr->data;
295
	  is_ll = 0;
294

  
295
	  /* We have two addresses here in 'nh'. Really. */
296
	  ipp = (ip_addr *) nh->u.ptr->data;
297
	  ip = ipp[0];
298
	  ip_ll = IPA_NONE;
299

  
296 300
	  if (ipa_equal(ip, p->source_addr))
297
	    {
298
	      is_ll = 1;
299
	      ip_ll = p->local_link;
300
	    }
301
	    ip_ll = p->local_link;
301 302
	  else
302 303
	    {
304
	      /* If we send a route with 'third party' next hop destinated 
305
	       * in the same interface, we should also send a link local 
306
	       * next hop address. We use the received one (stored in the 
307
	       * other part of BA_NEXT_HOP eattr). If we didn't received
308
	       * it (for example it is a static route), we do not send link
309
	       * local next hop address. It is contrary to RFC 2545, but
310
	       * probably the only sane possibility.
311
	       */
312

  
303 313
	      n = neigh_find(&p->p, &ip, 0);
304 314
	      if (n && n->iface == p->neigh->iface)
305
		{
306
		  /* FIXME: We are assuming the global scope addresses use the lower 64 bits
307
		   * as an interface identifier which hasn't necessarily to be true.
308
		   */
309
		  is_ll = 1;
310
	          ip_ll = ipa_or(ipa_build(0xfe800000,0,0,0), ipa_and(ip, ipa_build(0,0,~0,~0)));
311
		}
315
		ip_ll = ipp[1];
312 316
	    }
313
	  if (is_ll)
317

  
318
	  if (ipa_nonzero(ip_ll))
314 319
	    {
315 320
	      *tmp++ = 32;
316 321
	      ipa_hton(ip);
......
326 331
	      memcpy(tmp, &ip, 16);
327 332
	      tmp += 16;
328 333
	    }
334

  
329 335
	  *tmp++ = 0;			/* No SNPA information */
330 336
	  tmp += bgp_encode_prefixes(p, tmp, buck, remains - (8+3+32+1));
331 337
	  ea->attrs[0].u.ptr->length = tmp - tstart;
......
778 784
      if (len < 1 || (*x != 16 && *x != 32) || len < *x + 2)
779 785
	goto bad;
780 786

  
781
      byte *nh = bgp_attach_attr_wa(&a0->eattrs, bgp_linpool, BA_NEXT_HOP, 16);
787
      ip_addr *nh = (ip_addr *) bgp_attach_attr_wa(&a0->eattrs, bgp_linpool, BA_NEXT_HOP, NEXT_HOP_LENGTH);
782 788
      memcpy(nh, x+1, 16);
783
      ipa_ntoh(*(ip_addr *)nh);
789
      ipa_ntoh(nh[0]);
790

  
791
      /* We store received link local address in the other part of BA_NEXT_HOP eattr. */
792
      if (*x == 32)
793
	{
794
	  memcpy(nh+1, x+17, 16);
795
	  ipa_ntoh(nh[1]);
796
	}
797
      else
798
	nh[1] = IPA_NONE;
784 799

  
785 800
      /* Also ignore one reserved byte */
786 801
      len -= *x + 2;

Also available in: Unified diff