]>
git.ipfire.org Git - thirdparty/bird.git/blob - proto/bgp/packets.c
2 * BIRD -- BGP Packet Processing
4 * (c) 2000 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
11 #include "nest/bird.h"
12 #include "nest/iface.h"
13 #include "nest/protocol.h"
14 #include "nest/route.h"
15 #include "nest/attrs.h"
16 #include "nest/mrtdump.h"
17 #include "conf/conf.h"
18 #include "lib/unaligned.h"
19 #include "lib/socket.h"
25 static struct rate_limit rl_rcv_update
, rl_snd_update
;
28 * MRT Dump format is not semantically specified.
29 * We will use these values in appropriate fields:
31 * Local AS, Remote AS - configured AS numbers for given BGP instance.
32 * Local IP, Remote IP - IP addresses of the TCP connection (0 if no connection)
34 * We dump two kinds of MRT messages: STATE_CHANGE (for BGP state
35 * changes) and MESSAGE (for received BGP messages).
37 * STATE_CHANGE uses always AS4 variant, but MESSAGE uses AS4 variant
38 * only when AS4 session is established and even in that case MESSAGE
39 * does not use AS4 variant for initial OPEN message. This strange
40 * behavior is here for compatibility with Quagga and Bgpdump,
44 mrt_put_bgp4_hdr ( byte
* buf
, struct bgp_conn
* conn
, int as4
)
46 struct bgp_proto
* p
= conn
-> bgp
;
50 put_u32 ( buf
+ 0 , p
-> remote_as
);
51 put_u32 ( buf
+ 4 , p
-> local_as
);
56 put_u16 ( buf
+ 0 , ( p
-> remote_as
<= 0xFFFF ) ? p
-> remote_as
: AS_TRANS
);
57 put_u16 ( buf
+ 2 , ( p
-> local_as
<= 0xFFFF ) ? p
-> local_as
: AS_TRANS
);
61 put_u16 ( buf
+ 0 , p
-> neigh
? p
-> neigh
-> iface
-> index
: 0 );
62 put_u16 ( buf
+ 2 , BGP_AF
);
64 buf
= ipa_put_addr ( buf
, conn
-> sk
? conn
-> sk
-> daddr
: IPA_NONE
);
65 buf
= ipa_put_addr ( buf
, conn
-> sk
? conn
-> sk
-> saddr
: IPA_NONE
);
71 mrt_dump_bgp_packet ( struct bgp_conn
* conn
, byte
* pkt
, unsigned len
)
73 byte buf
[ BGP_MAX_PACKET_LENGTH
+ 128 ];
74 byte
* bp
= buf
+ MRTDUMP_HDR_LENGTH
;
75 int as4
= conn
-> bgp
-> as4_session
;
77 bp
= mrt_put_bgp4_hdr ( bp
, conn
, as4
);
80 mrt_dump_message (& conn
-> bgp
-> p
, BGP4MP
, as4
? BGP4MP_MESSAGE_AS4
: BGP4MP_MESSAGE
,
85 convert_state ( unsigned state
)
87 /* Convert state from our BS_* values to values used in MRTDump */
88 return ( state
== BS_CLOSE
) ? 1 : state
+ 1 ;
92 mrt_dump_bgp_state_change ( struct bgp_conn
* conn
, unsigned old
, unsigned new )
95 byte
* bp
= buf
+ MRTDUMP_HDR_LENGTH
;
97 bp
= mrt_put_bgp4_hdr ( bp
, conn
, 1 );
98 put_u16 ( bp
+ 0 , convert_state ( old
));
99 put_u16 ( bp
+ 2 , convert_state ( new ));
101 mrt_dump_message (& conn
-> bgp
-> p
, BGP4MP
, BGP4MP_STATE_CHANGE_AS4
, buf
, bp
- buf
);
105 bgp_create_notification ( struct bgp_conn
* conn
, byte
* buf
)
107 struct bgp_proto
* p
= conn
-> bgp
;
109 BGP_TRACE ( D_PACKETS
, "Sending NOTIFICATION(code=%d.%d)" , conn
-> notify_code
, conn
-> notify_subcode
);
110 buf
[ 0 ] = conn
-> notify_code
;
111 buf
[ 1 ] = conn
-> notify_subcode
;
112 memcpy ( buf
+ 2 , conn
-> notify_data
, conn
-> notify_size
);
113 return buf
+ 2 + conn
-> notify_size
;
118 bgp_put_cap_ipv6 ( struct bgp_conn
* conn UNUSED
, byte
* buf
)
120 * buf
++ = 1 ; /* Capability 1: Multiprotocol extensions */
121 * buf
++ = 4 ; /* Capability data length */
122 * buf
++ = 0 ; /* We support AF IPv6 */
123 * buf
++ = BGP_AF_IPV6
;
124 * buf
++ = 0 ; /* RFU */
125 * buf
++ = 1 ; /* and SAFI 1 */
132 bgp_put_cap_ipv4 ( struct bgp_conn
* conn UNUSED
, byte
* buf
)
134 * buf
++ = 1 ; /* Capability 1: Multiprotocol extensions */
135 * buf
++ = 4 ; /* Capability data length */
136 * buf
++ = 0 ; /* We support AF IPv4 */
137 * buf
++ = BGP_AF_IPV4
;
138 * buf
++ = 0 ; /* RFU */
139 * buf
++ = 1 ; /* and SAFI 1 */
145 bgp_put_cap_rr ( struct bgp_conn
* conn UNUSED
, byte
* buf
)
147 * buf
++ = 2 ; /* Capability 2: Support for route refresh */
148 * buf
++ = 0 ; /* Capability data length */
153 bgp_put_cap_as4 ( struct bgp_conn
* conn
, byte
* buf
)
155 * buf
++ = 65 ; /* Capability 65: Support for 4-octet AS number */
156 * buf
++ = 4 ; /* Capability data length */
157 put_u32 ( buf
, conn
-> bgp
-> local_as
);
162 bgp_create_open ( struct bgp_conn
* conn
, byte
* buf
)
164 struct bgp_proto
* p
= conn
-> bgp
;
168 BGP_TRACE ( D_PACKETS
, "Sending OPEN(ver=%d,as=%d,hold=%d,id=%08x)" ,
169 BGP_VERSION
, p
-> local_as
, p
-> cf
-> hold_time
, p
-> local_id
);
170 buf
[ 0 ] = BGP_VERSION
;
171 put_u16 ( buf
+ 1 , ( p
-> local_as
< 0xFFFF ) ? p
-> local_as
: AS_TRANS
);
172 put_u16 ( buf
+ 3 , p
-> cf
-> hold_time
);
173 put_u32 ( buf
+ 5 , p
-> local_id
);
175 if ( conn
-> start_state
== BSS_CONNECT_NOCAP
)
177 BGP_TRACE ( D_PACKETS
, "Skipping capabilities" );
182 /* Skipped 3 B for length field and Capabilities parameter header */
186 if ( p
-> cf
-> advertise_ipv4
)
187 cap
= bgp_put_cap_ipv4 ( conn
, cap
);
191 cap
= bgp_put_cap_ipv6 ( conn
, cap
);
194 if ( p
-> cf
-> enable_refresh
)
195 cap
= bgp_put_cap_rr ( conn
, cap
);
197 if ( conn
-> want_as4_support
)
198 cap
= bgp_put_cap_as4 ( conn
, cap
);
200 cap_len
= cap
- buf
- 12 ;
203 buf
[ 9 ] = cap_len
+ 2 ; /* Optional params len */
204 buf
[ 10 ] = 2 ; /* Option: Capability list */
205 buf
[ 11 ] = cap_len
; /* Option length */
210 buf
[ 9 ] = 0 ; /* No optional parameters */
216 bgp_encode_prefixes ( struct bgp_proto
* p
, byte
* w
, struct bgp_bucket
* buck
, unsigned int remains
)
222 while (! EMPTY_LIST ( buck
-> prefixes
) && remains
>= ( 1 + sizeof ( ip_addr
)))
224 struct bgp_prefix
* px
= SKIP_BACK ( struct bgp_prefix
, bucket_node
, HEAD ( buck
-> prefixes
));
225 DBG ( " \t Dequeued route %I/%d \n " , px
-> n
. prefix
, px
-> n
. pxlen
);
227 bytes
= ( px
-> n
. pxlen
+ 7 ) / 8 ;
230 memcpy ( w
, & a
, bytes
);
232 remains
-= bytes
+ 1 ;
233 rem_node (& px
-> bucket_node
);
234 fib_delete (& p
-> prefix_fib
, px
);
240 bgp_flush_prefixes ( struct bgp_proto
* p
, struct bgp_bucket
* buck
)
242 while (! EMPTY_LIST ( buck
-> prefixes
))
244 struct bgp_prefix
* px
= SKIP_BACK ( struct bgp_prefix
, bucket_node
, HEAD ( buck
-> prefixes
));
245 log ( L_ERR
"%s: - route %I/%d skipped" , p
-> p
. name
, px
-> n
. prefix
, px
-> n
. pxlen
);
246 rem_node (& px
-> bucket_node
);
247 fib_delete (& p
-> prefix_fib
, px
);
251 #ifndef IPV6 /* IPv4 version */
254 bgp_create_update ( struct bgp_conn
* conn
, byte
* buf
)
256 struct bgp_proto
* p
= conn
-> bgp
;
257 struct bgp_bucket
* buck
;
258 int remains
= BGP_MAX_PACKET_LENGTH
- BGP_HEADER_LENGTH
- 4 ;
265 if (( buck
= p
-> withdraw_bucket
) && ! EMPTY_LIST ( buck
-> prefixes
))
267 DBG ( "Withdrawn routes: \n " );
268 wd_size
= bgp_encode_prefixes ( p
, w
, buck
, remains
);
272 put_u16 ( buf
, wd_size
);
276 while (( buck
= ( struct bgp_bucket
*) HEAD ( p
-> bucket_queue
))-> send_node
. next
)
278 if ( EMPTY_LIST ( buck
-> prefixes
))
280 DBG ( "Deleting empty bucket %p \n " , buck
);
281 rem_node (& buck
-> send_node
);
282 bgp_free_bucket ( p
, buck
);
286 DBG ( "Processing bucket %p \n " , buck
);
287 a_size
= bgp_encode_attrs ( p
, w
+ 2 , buck
-> eattrs
, 2048 );
291 log ( L_ERR
"%s: Attribute list too long, skipping corresponding routes" , p
-> p
. name
);
292 bgp_flush_prefixes ( p
, buck
);
293 rem_node (& buck
-> send_node
);
294 bgp_free_bucket ( p
, buck
);
300 r_size
= bgp_encode_prefixes ( p
, w
, buck
, remains
- a_size
);
305 if (! a_size
) /* Attributes not already encoded */
310 if ( wd_size
|| r_size
)
312 BGP_TRACE_RL (& rl_snd_update
, D_PACKETS
, "Sending UPDATE" );
319 #else /* IPv6 version */
322 same_iface ( struct bgp_proto
* p
, ip_addr
* ip
)
324 neighbor
* n
= neigh_find (& p
-> p
, ip
, 0 );
325 return n
&& p
-> neigh
&& n
-> iface
== p
-> neigh
-> iface
;
329 bgp_create_update ( struct bgp_conn
* conn
, byte
* buf
)
331 struct bgp_proto
* p
= conn
-> bgp
;
332 struct bgp_bucket
* buck
;
333 int size
, second
, rem_stored
;
334 int remains
= BGP_MAX_PACKET_LENGTH
- BGP_HEADER_LENGTH
- 4 ;
335 byte
* w
, * w_stored
, * tmp
, * tstart
;
336 ip_addr
* ipp
, ip
, ip_ll
;
343 if (( buck
= p
-> withdraw_bucket
) && ! EMPTY_LIST ( buck
-> prefixes
))
345 DBG ( "Withdrawn routes: \n " );
346 tmp
= bgp_attach_attr_wa (& ea
, bgp_linpool
, BA_MP_UNREACH_NLRI
, remains
- 8 );
348 * tmp
++ = BGP_AF_IPV6
;
350 ea
-> attrs
[ 0 ]. u
. ptr
-> length
= 3 + bgp_encode_prefixes ( p
, tmp
, buck
, remains
- 11 );
351 size
= bgp_encode_attrs ( p
, w
, ea
, remains
);
359 while (( buck
= ( struct bgp_bucket
*) HEAD ( p
-> bucket_queue
))-> send_node
. next
)
361 if ( EMPTY_LIST ( buck
-> prefixes
))
363 DBG ( "Deleting empty bucket %p \n " , buck
);
364 rem_node (& buck
-> send_node
);
365 bgp_free_bucket ( p
, buck
);
369 DBG ( "Processing bucket %p \n " , buck
);
370 rem_stored
= remains
;
373 size
= bgp_encode_attrs ( p
, w
, buck
-> eattrs
, 2048 );
376 log ( L_ERR
"%s: Attribute list too long, skipping corresponding routes" , p
-> p
. name
);
377 bgp_flush_prefixes ( p
, buck
);
378 rem_node (& buck
-> send_node
);
379 bgp_free_bucket ( p
, buck
);
385 /* We have two addresses here in NEXT_HOP eattr. Really.
386 Unless NEXT_HOP was modified by filter */
387 nh
= ea_find ( buck
-> eattrs
, EA_CODE ( EAP_BGP
, BA_NEXT_HOP
));
389 second
= ( nh
-> u
. ptr
-> length
== NEXT_HOP_LENGTH
);
390 ipp
= ( ip_addr
*) nh
-> u
. ptr
-> data
;
394 if ( ipa_equal ( ip
, p
-> source_addr
))
395 ip_ll
= p
-> local_link
;
398 /* If we send a route with 'third party' next hop destinated
399 * in the same interface, we should also send a link local
400 * next hop address. We use the received one (stored in the
401 * other part of BA_NEXT_HOP eattr). If we didn't received
402 * it (for example it is a static route), we can't use
403 * 'third party' next hop and we have to use local IP address
404 * as next hop. Sending original next hop address without
405 * link local address seems to be a natural way to solve that
406 * problem, but it is contrary to RFC 2545 and Quagga does not
407 * accept such routes.
409 * There are two cases, either we have global IP, or
410 * IPA_NONE if the neighbor is link-local. For IPA_NONE,
411 * we suppose it is on the same iface, see bgp_update_attrs().
414 if ( ipa_zero ( ip
) || same_iface ( p
, & ip
))
416 if ( second
&& ipa_nonzero ( ipp
[ 1 ]))
420 switch ( p
-> cf
-> missing_lladdr
)
424 ip_ll
= p
-> local_link
;
427 log ( L_ERR
"%s: Missing link-local next hop address, skipping corresponding routes" , p
-> p
. name
);
429 remains
= rem_stored
;
430 bgp_flush_prefixes ( p
, buck
);
431 rem_node (& buck
-> send_node
);
432 bgp_free_bucket ( p
, buck
);
441 tstart
= tmp
= bgp_attach_attr_wa (& ea
, bgp_linpool
, BA_MP_REACH_NLRI
, remains
- 8 );
443 * tmp
++ = BGP_AF_IPV6
;
446 if ( ipa_has_link_scope ( ip
))
449 if ( ipa_nonzero ( ip_ll
))
453 memcpy ( tmp
, & ip
, 16 );
455 memcpy ( tmp
+ 16 , & ip_ll
, 16 );
462 memcpy ( tmp
, & ip
, 16 );
466 * tmp
++ = 0 ; /* No SNPA information */
467 tmp
+= bgp_encode_prefixes ( p
, tmp
, buck
, remains
- ( 8 + 3 + 32 + 1 ));
468 ea
-> attrs
[ 0 ]. u
. ptr
-> length
= tmp
- tstart
;
469 size
= bgp_encode_attrs ( p
, w
, ea
, remains
);
477 put_u16 ( buf
+ 2 , size
);
478 lp_flush ( bgp_linpool
);
481 BGP_TRACE_RL (& rl_snd_update
, D_PACKETS
, "Sending UPDATE" );
491 bgp_create_route_refresh ( struct bgp_conn
* conn
, byte
* buf
)
493 struct bgp_proto
* p
= conn
-> bgp
;
494 BGP_TRACE ( D_PACKETS
, "Sending ROUTE-REFRESH" );
498 * buf
++ = 0 ; /* RFU */
499 * buf
++ = 1 ; /* and SAFI 1 */
504 bgp_create_header ( byte
* buf
, unsigned int len
, unsigned int type
)
506 memset ( buf
, 0xff , 16 ); /* Marker */
507 put_u16 ( buf
+ 16 , len
);
512 * bgp_fire_tx - transmit packets
515 * Whenever the transmit buffers of the underlying TCP connection
516 * are free and we have any packets queued for sending, the socket functions
517 * call bgp_fire_tx() which takes care of selecting the highest priority packet
518 * queued (Notification > Keepalive > Open > Update), assembling its header
519 * and body and sending it to the connection.
522 bgp_fire_tx ( struct bgp_conn
* conn
)
524 struct bgp_proto
* p
= conn
-> bgp
;
525 unsigned int s
= conn
-> packets_to_send
;
527 byte
* buf
, * pkt
, * end
;
532 conn
-> packets_to_send
= 0 ;
536 pkt
= buf
+ BGP_HEADER_LENGTH
;
538 if ( s
& ( 1 << PKT_SCHEDULE_CLOSE
))
540 /* We can finally close connection and enter idle state */
541 bgp_conn_enter_idle_state ( conn
);
544 if ( s
& ( 1 << PKT_NOTIFICATION
))
546 s
= 1 << PKT_SCHEDULE_CLOSE
;
547 type
= PKT_NOTIFICATION
;
548 end
= bgp_create_notification ( conn
, pkt
);
550 else if ( s
& ( 1 << PKT_KEEPALIVE
))
552 s
&= ~( 1 << PKT_KEEPALIVE
);
553 type
= PKT_KEEPALIVE
;
554 end
= pkt
; /* Keepalives carry no data */
555 BGP_TRACE ( D_PACKETS
, "Sending KEEPALIVE" );
556 bgp_start_timer ( conn
-> keepalive_timer
, conn
-> keepalive_time
);
558 else if ( s
& ( 1 << PKT_OPEN
))
560 s
&= ~( 1 << PKT_OPEN
);
562 end
= bgp_create_open ( conn
, pkt
);
564 else if ( s
& ( 1 << PKT_ROUTE_REFRESH
))
566 s
&= ~( 1 << PKT_ROUTE_REFRESH
);
567 type
= PKT_ROUTE_REFRESH
;
568 end
= bgp_create_route_refresh ( conn
, pkt
);
570 else if ( s
& ( 1 << PKT_UPDATE
))
572 end
= bgp_create_update ( conn
, pkt
);
576 conn
-> packets_to_send
= 0 ;
582 conn
-> packets_to_send
= s
;
583 bgp_create_header ( buf
, end
- buf
, type
);
584 return sk_send ( sk
, end
- buf
);
588 * bgp_schedule_packet - schedule a packet for transmission
592 * Schedule a packet of type @type to be sent as soon as possible.
595 bgp_schedule_packet ( struct bgp_conn
* conn
, int type
)
597 DBG ( "BGP: Scheduling packet type %d \n " , type
);
598 conn
-> packets_to_send
|= 1 << type
;
599 if ( conn
-> sk
&& conn
-> sk
-> tpos
== conn
-> sk
-> tbuf
)
600 ev_schedule ( conn
-> tx_ev
);
604 bgp_kick_tx ( void * vconn
)
606 struct bgp_conn
* conn
= vconn
;
608 DBG ( "BGP: kicking TX \n " );
609 while ( bgp_fire_tx ( conn
) > 0 )
616 struct bgp_conn
* conn
= sk
-> data
;
618 DBG ( "BGP: TX hook \n " );
619 while ( bgp_fire_tx ( conn
) > 0 )
623 /* Capatibility negotiation as per RFC 2842 */
626 bgp_parse_capabilities ( struct bgp_conn
* conn
, byte
* opt
, int len
)
628 // struct bgp_proto *p = conn->bgp;
633 if ( len
< 2 || len
< 2 + opt
[ 1 ])
640 case 2 : /* Route refresh capability, RFC 2918 */
643 conn
-> peer_refresh_support
= 1 ;
646 case 65 : /* AS4 capability, RFC 4893 */
649 conn
-> peer_as4_support
= 1 ;
650 if ( conn
-> want_as4_support
)
651 conn
-> advertised_as
= get_u32 ( opt
+ 2 );
654 /* We can safely ignore all other capabilities */
662 bgp_error ( conn
, 2 , 0 , NULL
, 0 );
667 bgp_parse_options ( struct bgp_conn
* conn
, byte
* opt
, int len
)
669 struct bgp_proto
* p
= conn
-> bgp
;
674 if ( len
< 2 || len
< 2 + opt
[ 1 ])
675 { bgp_error ( conn
, 2 , 0 , NULL
, 0 ); return 0 ; }
679 DBG ( " \t Option %02x:" , opt
[ 0 ]);
680 for ( i
= 0 ; i
< opt
[ 1 ]; i
++)
681 DBG ( " %02x" , opt
[ 2 + i
]);
690 if ( conn
-> start_state
== BSS_CONNECT_NOCAP
)
691 BGP_TRACE ( D_PACKETS
, "Ignoring received capabilities" );
693 bgp_parse_capabilities ( conn
, opt
+ 2 , ol
);
698 * BGP specs don't tell us to send which option
699 * we didn't recognize, but it's common practice
700 * to do so. Also, capability negotiation with
701 * Cisco routers doesn't work without that.
703 bgp_error ( conn
, 2 , 4 , opt
, ol
);
713 bgp_rx_open ( struct bgp_conn
* conn
, byte
* pkt
, int len
)
715 struct bgp_conn
* other
;
716 struct bgp_proto
* p
= conn
-> bgp
;
722 if ( conn
-> state
!= BS_OPENSENT
)
723 { bgp_error ( conn
, 5 , 0 , NULL
, 0 ); return ; }
725 /* Check message contents */
726 if ( len
< 29 || len
!= 29 + pkt
[ 28 ])
727 { bgp_error ( conn
, 1 , 2 , pkt
+ 16 , 2 ); return ; }
728 if ( pkt
[ 19 ] != BGP_VERSION
)
729 { bgp_error ( conn
, 2 , 1 , pkt
+ 19 , 1 ); return ; } /* RFC 1771 says 16 bits, draft-09 tells to use 8 */
730 conn
-> advertised_as
= base_as
= get_u16 ( pkt
+ 20 );
731 hold
= get_u16 ( pkt
+ 22 );
732 id
= get_u32 ( pkt
+ 24 );
733 BGP_TRACE ( D_PACKETS
, "Got OPEN(as=%d,hold=%d,id=%08x)" , conn
-> advertised_as
, hold
, id
);
735 if ( bgp_parse_options ( conn
, pkt
+ 29 , pkt
[ 28 ]))
738 if ( hold
> 0 && hold
< 3 )
739 { bgp_error ( conn
, 2 , 6 , pkt
+ 22 , 2 ); return ; }
741 if (! id
|| id
== 0xffffffff || id
== p
-> local_id
)
742 { bgp_error ( conn
, 2 , 3 , pkt
+ 24 , - 4 ); return ; }
744 if (( conn
-> advertised_as
!= base_as
) && ( base_as
!= AS_TRANS
))
745 log ( L_WARN
"%s: Peer advertised inconsistent AS numbers" , p
-> p
. name
);
747 if ( conn
-> advertised_as
!= p
-> remote_as
)
749 if ( conn
-> peer_as4_support
)
751 u32 val
= htonl ( conn
-> advertised_as
);
752 bgp_error ( conn
, 2 , 2 , ( byte
*) & val
, 4 );
755 bgp_error ( conn
, 2 , 2 , pkt
+ 20 , 2 );
760 /* Check the other connection */
761 other
= ( conn
== & p
-> outgoing_conn
) ? & p
-> incoming_conn
: & p
-> outgoing_conn
;
762 switch ( other
-> state
)
771 if (( p
-> local_id
< id
) == ( conn
== & p
-> incoming_conn
))
773 /* Should close the other connection */
774 BGP_TRACE ( D_EVENTS
, "Connection collision, giving up the other connection" );
775 bgp_error ( other
, 6 , 7 , NULL
, 0 );
780 /* Should close this connection */
781 BGP_TRACE ( D_EVENTS
, "Connection collision, giving up this connection" );
782 bgp_error ( conn
, 6 , 7 , NULL
, 0 );
785 bug ( "bgp_rx_open: Unknown state" );
788 /* Update our local variables */
789 conn
-> hold_time
= MIN ( hold
, p
-> cf
-> hold_time
);
790 conn
-> keepalive_time
= p
-> cf
-> keepalive_time
? : conn
-> hold_time
/ 3 ;
792 p
-> as4_session
= conn
-> want_as4_support
&& conn
-> peer_as4_support
;
794 DBG ( "BGP: Hold timer set to %d, keepalive to %d, AS to %d, ID to %x, AS4 session to %d \n " , conn
-> hold_time
, conn
-> keepalive_time
, p
-> remote_as
, p
-> remote_id
, p
-> as4_session
);
796 bgp_schedule_packet ( conn
, PKT_KEEPALIVE
);
797 bgp_start_timer ( conn
-> hold_timer
, conn
-> hold_time
);
798 bgp_conn_enter_openconfirm_state ( conn
);
801 #define DECODE_PREFIX(pp, ll) do { \
805 if (b > BITS_PER_IP_ADDRESS) { err=10; goto done; } \
807 if (ll < q) { err=1; goto done; } \
808 memcpy(&prefix, pp, q); \
812 prefix = ipa_and(prefix, ipa_mkmask(b)); \
817 bgp_set_next_hop ( struct bgp_proto
* p
, rta
* a
)
819 struct eattr
* nh
= ea_find ( a
-> eattrs
, EA_CODE ( EAP_BGP
, BA_NEXT_HOP
));
820 ip_addr
* nexthop
= ( ip_addr
*) nh
-> u
. ptr
-> data
;
823 int second
= ( nh
-> u
. ptr
-> length
== NEXT_HOP_LENGTH
);
825 /* First address should not be link-local, but may be zero in direct mode */
826 if ( ipa_has_link_scope (* nexthop
))
832 if ( p
-> cf
-> gw_mode
== GW_DIRECT
)
836 if ( ipa_nonzero (* nexthop
))
837 ng
= neigh_find (& p
-> p
, nexthop
, 0 );
838 else if ( second
) /* GW_DIRECT -> single_hop -> p->neigh != NULL */
839 ng
= neigh_find2 (& p
-> p
, nexthop
+ 1 , p
-> neigh
-> iface
, 0 );
845 if ( ng
-> scope
== SCOPE_HOST
)
848 a
-> dest
= RTD_ROUTER
;
850 a
-> iface
= ng
-> iface
;
854 else /* GW_RECURSIVE */
856 if ( ipa_zero (* nexthop
))
859 rta_set_recursive_next_hop ( p
-> p
. table
, a
, p
-> igp_table
, nexthop
, nexthop
+ second
);
865 #ifndef IPV6 /* IPv4 version */
868 bgp_do_rx_update ( struct bgp_conn
* conn
,
869 byte
* withdrawn
, int withdrawn_len
,
870 byte
* nlri
, int nlri_len
,
871 byte
* attrs
, int attr_len
)
873 struct bgp_proto
* p
= conn
-> bgp
;
879 /* Withdraw routes */
880 while ( withdrawn_len
)
882 DECODE_PREFIX ( withdrawn
, withdrawn_len
);
883 DBG ( "Withdraw %I/%d \n " , prefix
, pxlen
);
884 if ( n
= net_find ( p
-> p
. table
, prefix
, pxlen
))
885 rte_update ( p
-> p
. table
, n
, & p
-> p
, & p
-> p
, NULL
);
888 if (! attr_len
&& ! nlri_len
) /* shortcut */
891 a0
= bgp_decode_attrs ( conn
, attrs
, attr_len
, bgp_linpool
, nlri_len
);
893 if ( conn
-> state
!= BS_ESTABLISHED
) /* fatal error during decoding */
896 if ( a0
&& nlri_len
&& bgp_set_next_hop ( p
, a0
))
901 DECODE_PREFIX ( nlri
, nlri_len
);
902 DBG ( "Add %I/%d \n " , prefix
, pxlen
);
906 rte
* e
= rte_get_temp ( rta_clone ( a
));
907 e
-> net
= net_get ( p
-> p
. table
, prefix
, pxlen
);
909 e
-> u
. bgp
. suppressed
= 0 ;
910 rte_update ( p
-> p
. table
, e
-> net
, & p
-> p
, & p
-> p
, e
);
914 /* Forced withdraw as a result of soft error */
915 if ( n
= net_find ( p
-> p
. table
, prefix
, pxlen
))
916 rte_update ( p
-> p
. table
, n
, & p
-> p
, & p
-> p
, NULL
);
925 bgp_error ( conn
, 3 , err
, NULL
, 0 );
930 #else /* IPv6 version */
932 #define DO_NLRI(name) \
933 start = x = p->name##_start; \
934 len = len0 = p->name##_len; \
937 if (len < 3) { err=9; goto done; } \
942 DBG( " \t NLRI AF=%d sub=%d len=%d \n " , af, sub, len);\
946 if (af == BGP_AF_IPV6)
949 bgp_attach_next_hop ( rta
* a0
, byte
* x
)
951 ip_addr
* nh
= ( ip_addr
*) bgp_attach_attr_wa (& a0
-> eattrs
, bgp_linpool
, BA_NEXT_HOP
, NEXT_HOP_LENGTH
);
955 /* We store received link local address in the other part of BA_NEXT_HOP eattr. */
958 memcpy ( nh
+ 1 , x
+ 17 , 16 );
967 bgp_do_rx_update ( struct bgp_conn
* conn
,
968 byte
* withdrawn
, int withdrawn_len
,
969 byte
* nlri
, int nlri_len
,
970 byte
* attrs
, int attr_len
)
972 struct bgp_proto
* p
= conn
-> bgp
;
982 p
-> mp_unreach_len
= 0 ;
983 a0
= bgp_decode_attrs ( conn
, attrs
, attr_len
, bgp_linpool
, 0 );
985 if ( conn
-> state
!= BS_ESTABLISHED
) /* fatal error during decoding */
992 DECODE_PREFIX ( x
, len
);
993 DBG ( "Withdraw %I/%d \n " , prefix
, pxlen
);
994 if ( n
= net_find ( p
-> p
. table
, prefix
, pxlen
))
995 rte_update ( p
-> p
. table
, n
, & p
-> p
, & p
-> p
, NULL
);
1001 /* Create fake NEXT_HOP attribute */
1002 if ( len
< 1 || (* x
!= 16 && * x
!= 32 ) || len
< * x
+ 2 )
1003 { err
= 9 ; goto done
; }
1006 bgp_attach_next_hop ( a0
, x
);
1008 /* Also ignore one reserved byte */
1012 if ( a0
&& bgp_set_next_hop ( p
, a0
))
1017 DECODE_PREFIX ( x
, len
);
1018 DBG ( "Add %I/%d \n " , prefix
, pxlen
);
1022 rte
* e
= rte_get_temp ( rta_clone ( a
));
1023 e
-> net
= net_get ( p
-> p
. table
, prefix
, pxlen
);
1025 e
-> u
. bgp
. suppressed
= 0 ;
1026 rte_update ( p
-> p
. table
, e
-> net
, & p
-> p
, & p
-> p
, e
);
1030 /* Forced withdraw as a result of soft error */
1031 if ( n
= net_find ( p
-> p
. table
, prefix
, pxlen
))
1032 rte_update ( p
-> p
. table
, n
, & p
-> p
, & p
-> p
, NULL
);
1041 if ( err
) /* Use subcode 9, not err */
1042 bgp_error ( conn
, 3 , 9 , NULL
, 0 );
1050 bgp_rx_update ( struct bgp_conn
* conn
, byte
* pkt
, int len
)
1052 struct bgp_proto
* p
= conn
-> bgp
;
1053 byte
* withdrawn
, * attrs
, * nlri
;
1054 int withdrawn_len
, attr_len
, nlri_len
;
1056 BGP_TRACE_RL (& rl_rcv_update
, D_PACKETS
, "Got UPDATE" );
1058 /* Workaround for some BGP implementations that skip initial KEEPALIVE */
1059 if ( conn
-> state
== BS_OPENCONFIRM
)
1060 bgp_conn_enter_established_state ( conn
);
1062 if ( conn
-> state
!= BS_ESTABLISHED
)
1063 { bgp_error ( conn
, 5 , 0 , NULL
, 0 ); return ; }
1064 bgp_start_timer ( conn
-> hold_timer
, conn
-> hold_time
);
1066 /* Find parts of the packet and check sizes */
1069 bgp_error ( conn
, 1 , 2 , pkt
+ 16 , 2 );
1072 withdrawn
= pkt
+ 21 ;
1073 withdrawn_len
= get_u16 ( pkt
+ 19 );
1074 if ( withdrawn_len
+ 23 > len
)
1076 attrs
= withdrawn
+ withdrawn_len
+ 2 ;
1077 attr_len
= get_u16 ( attrs
- 2 );
1078 if ( withdrawn_len
+ attr_len
+ 23 > len
)
1080 nlri
= attrs
+ attr_len
;
1081 nlri_len
= len
- withdrawn_len
- attr_len
- 23 ;
1082 if (! attr_len
&& nlri_len
)
1084 DBG ( "Sizes: withdrawn=%d, attrs=%d, NLRI=%d \n " , withdrawn_len
, attr_len
, nlri_len
);
1086 lp_flush ( bgp_linpool
);
1088 bgp_do_rx_update ( conn
, withdrawn
, withdrawn_len
, nlri
, nlri_len
, attrs
, attr_len
);
1092 bgp_error ( conn
, 3 , 1 , NULL
, 0 );
1098 } bgp_msg_table
[] = {
1099 { 1 , 0 , "Invalid message header" },
1100 { 1 , 1 , "Connection not synchronized" },
1101 { 1 , 2 , "Bad message length" },
1102 { 1 , 3 , "Bad message type" },
1103 { 2 , 0 , "Invalid OPEN message" },
1104 { 2 , 1 , "Unsupported version number" },
1105 { 2 , 2 , "Bad peer AS" },
1106 { 2 , 3 , "Bad BGP identifier" },
1107 { 2 , 4 , "Unsupported optional parameter" },
1108 { 2 , 5 , "Authentication failure" },
1109 { 2 , 6 , "Unacceptable hold time" },
1110 { 2 , 7 , "Required capability missing" }, /* [RFC3392] */
1111 { 2 , 8 , "No supported AFI/SAFI" }, /* This error msg is nonstandard */
1112 { 3 , 0 , "Invalid UPDATE message" },
1113 { 3 , 1 , "Malformed attribute list" },
1114 { 3 , 2 , "Unrecognized well-known attribute" },
1115 { 3 , 3 , "Missing mandatory attribute" },
1116 { 3 , 4 , "Invalid attribute flags" },
1117 { 3 , 5 , "Invalid attribute length" },
1118 { 3 , 6 , "Invalid ORIGIN attribute" },
1119 { 3 , 7 , "AS routing loop" }, /* Deprecated */
1120 { 3 , 8 , "Invalid NEXT_HOP attribute" },
1121 { 3 , 9 , "Optional attribute error" },
1122 { 3 , 10 , "Invalid network field" },
1123 { 3 , 11 , "Malformed AS_PATH" },
1124 { 4 , 0 , "Hold timer expired" },
1125 { 5 , 0 , "Finite state machine error" },
1126 { 6 , 0 , "Cease" }, /* Subcodes are according to [RFC4486] */
1127 { 6 , 1 , "Maximum number of prefixes reached" },
1128 { 6 , 2 , "Administrative shutdown" },
1129 { 6 , 3 , "Peer de-configured" },
1130 { 6 , 4 , "Administrative reset" },
1131 { 6 , 5 , "Connection rejected" },
1132 { 6 , 6 , "Other configuration change" },
1133 { 6 , 7 , "Connection collision resolution" },
1134 { 6 , 8 , "Out of Resources" }
1138 * bgp_error_dsc - return BGP error description
1139 * @code: BGP error code
1140 * @subcode: BGP error subcode
1142 * bgp_error_dsc() returns error description for BGP errors
1143 * which might be static string or given temporary buffer.
1146 bgp_error_dsc ( unsigned code
, unsigned subcode
)
1148 static char buff
[ 32 ];
1150 for ( i
= 0 ; i
< ARRAY_SIZE ( bgp_msg_table
); i
++)
1151 if ( bgp_msg_table
[ i
]. major
== code
&& bgp_msg_table
[ i
]. minor
== subcode
)
1153 return bgp_msg_table
[ i
]. msg
;
1156 bsprintf ( buff
, "Unknown error %d.%d" , code
, subcode
);
1161 bgp_log_error ( struct bgp_proto
* p
, u8
class , char * msg
, unsigned code
, unsigned subcode
, byte
* data
, unsigned len
)
1164 byte
* t
, argbuf
[ 36 ];
1167 /* Don't report Cease messages generated by myself */
1168 if ( code
== 6 && class == BE_BGP_TX
)
1171 name
= bgp_error_dsc ( code
, subcode
);
1178 if (( code
== 2 ) && ( subcode
== 2 ) && (( len
== 2 ) || ( len
== 4 )))
1180 /* Bad peer AS - we would like to print the AS */
1181 t
+= bsprintf ( t
, "%d" , ( len
== 2 ) ? get_u16 ( data
) : get_u32 ( data
));
1186 for ( i
= 0 ; i
< len
; i
++)
1187 t
+= bsprintf ( t
, "%02x" , data
[ i
]);
1191 log ( L_REMOTE
"%s: %s: %s%s" , p
-> p
. name
, msg
, name
, argbuf
);
1195 bgp_rx_notification ( struct bgp_conn
* conn
, byte
* pkt
, int len
)
1197 struct bgp_proto
* p
= conn
-> bgp
;
1200 bgp_error ( conn
, 1 , 2 , pkt
+ 16 , 2 );
1204 unsigned code
= pkt
[ 19 ];
1205 unsigned subcode
= pkt
[ 20 ];
1206 int err
= ( code
!= 6 );
1208 bgp_log_error ( p
, BE_BGP_RX
, "Received" , code
, subcode
, pkt
+ 21 , len
- 21 );
1209 bgp_store_error ( p
, conn
, BE_BGP_RX
, ( code
<< 16 ) | subcode
);
1212 if (( code
== 2 ) && (( subcode
== 4 ) || ( subcode
== 7 ))
1213 /* Error related to capability:
1214 * 4 - Peer does not support capabilities at all.
1215 * 7 - Peer request some capability. Strange unless it is IPv6 only peer.
1217 && ( p
-> cf
-> capabilities
== 2 )
1218 /* Capabilities are not explicitly enabled or disabled, therefore heuristic is used */
1219 && ( conn
-> start_state
== BSS_CONNECT
)
1220 /* Failed connection attempt have used capabilities */
1221 && ( p
-> cf
-> remote_as
<= 0xFFFF ))
1222 /* Not possible with disabled capabilities */
1224 /* We try connect without capabilities */
1225 log ( L_WARN
"%s: Capability related error received, retry with capabilities disabled" , p
-> p
. name
);
1226 p
-> start_state
= BSS_CONNECT_NOCAP
;
1231 bgp_conn_enter_close_state ( conn
);
1232 bgp_schedule_packet ( conn
, PKT_SCHEDULE_CLOSE
);
1236 bgp_update_startup_delay ( p
);
1242 bgp_rx_keepalive ( struct bgp_conn
* conn
)
1244 struct bgp_proto
* p
= conn
-> bgp
;
1246 BGP_TRACE ( D_PACKETS
, "Got KEEPALIVE" );
1247 bgp_start_timer ( conn
-> hold_timer
, conn
-> hold_time
);
1248 switch ( conn
-> state
)
1250 case BS_OPENCONFIRM
:
1251 bgp_conn_enter_established_state ( conn
);
1253 case BS_ESTABLISHED
:
1256 bgp_error ( conn
, 5 , 0 , NULL
, 0 );
1261 bgp_rx_route_refresh ( struct bgp_conn
* conn
, byte
* pkt
, int len
)
1263 struct bgp_proto
* p
= conn
-> bgp
;
1265 BGP_TRACE ( D_PACKETS
, "Got ROUTE-REFRESH" );
1267 if ( conn
-> state
!= BS_ESTABLISHED
)
1268 { bgp_error ( conn
, 5 , 0 , NULL
, 0 ); return ; }
1270 if (! p
-> cf
-> enable_refresh
)
1271 { bgp_error ( conn
, 1 , 3 , pkt
+ 18 , 1 ); return ; }
1273 if ( len
!= ( BGP_HEADER_LENGTH
+ 4 ))
1274 { bgp_error ( conn
, 1 , 2 , pkt
+ 16 , 2 ); return ; }
1276 /* FIXME - we ignore AFI/SAFI values, as we support
1277 just one value and even an error code for an invalid
1278 request is not defined */
1280 proto_request_feeding (& p
-> p
);
1285 * bgp_rx_packet - handle a received packet
1286 * @conn: BGP connection
1287 * @pkt: start of the packet
1290 * bgp_rx_packet() takes a newly received packet and calls the corresponding
1291 * packet handler according to the packet type.
1294 bgp_rx_packet ( struct bgp_conn
* conn
, byte
* pkt
, unsigned len
)
1296 byte type
= pkt
[ 18 ];
1298 DBG ( "BGP: Got packet %02x (%d bytes) \n " , type
, len
);
1300 if ( conn
-> bgp
-> p
. mrtdump
& MD_MESSAGES
)
1301 mrt_dump_bgp_packet ( conn
, pkt
, len
);
1305 case PKT_OPEN
: return bgp_rx_open ( conn
, pkt
, len
);
1306 case PKT_UPDATE
: return bgp_rx_update ( conn
, pkt
, len
);
1307 case PKT_NOTIFICATION
: return bgp_rx_notification ( conn
, pkt
, len
);
1308 case PKT_KEEPALIVE
: return bgp_rx_keepalive ( conn
);
1309 case PKT_ROUTE_REFRESH
: return bgp_rx_route_refresh ( conn
, pkt
, len
);
1310 default : bgp_error ( conn
, 1 , 3 , pkt
+ 18 , 1 );
1315 * bgp_rx - handle received data
1317 * @size: amount of data received
1319 * bgp_rx() is called by the socket layer whenever new data arrive from
1320 * the underlying TCP connection. It assembles the data fragments to packets,
1321 * checks their headers and framing and passes complete packets to
1325 bgp_rx ( sock
* sk
, int size
)
1327 struct bgp_conn
* conn
= sk
-> data
;
1328 byte
* pkt_start
= sk
-> rbuf
;
1329 byte
* end
= pkt_start
+ size
;
1332 DBG ( "BGP: RX hook: Got %d bytes \n " , size
);
1333 while ( end
>= pkt_start
+ BGP_HEADER_LENGTH
)
1335 if (( conn
-> state
== BS_CLOSE
) || ( conn
-> sk
!= sk
))
1338 if ( pkt_start
[ i
] != 0xff )
1340 bgp_error ( conn
, 1 , 1 , NULL
, 0 );
1343 len
= get_u16 ( pkt_start
+ 16 );
1344 if ( len
< BGP_HEADER_LENGTH
|| len
> BGP_MAX_PACKET_LENGTH
)
1346 bgp_error ( conn
, 1 , 2 , pkt_start
+ 16 , 2 );
1349 if ( end
< pkt_start
+ len
)
1351 bgp_rx_packet ( conn
, pkt_start
, len
);
1354 if ( pkt_start
!= sk
-> rbuf
)
1356 memmove ( sk
-> rbuf
, pkt_start
, end
- pkt_start
);
1357 sk
-> rpos
= sk
-> rbuf
+ ( end
- pkt_start
);