Tried your diff and it does allow the session to come up! Cool, thanks!
The FT Session TLV is silently ignored now, so it works with default Junos LDP
settings.

However it doesn't always come up now between two openbsd boxes. Check the log
message about
recieved notification from neighbor 192.168.100.1: Session Rejected, No Hello.
When I stopped and started both ldpd again, so I could also take a packet
trace, suddenly it worked. Will keep an eye on it. Anyhow, below the log
messages of openbsd2 that complained about the missing hello.

192.168.100.1 is openbsd1, 192.168.100.2 is openbsd2 (both are lo1
interfaces)


# ldpd -dv
fast = "2"
startup
kernel add route 0.0.0.0/0
if_fsm: event UP resulted in action START and changing state for interface em3
from DOWN to ACTIVE
kernel add route 192.168.56.0/24
if_fsm: event UP resulted in action START and changing state for interface em2
from DOWN to ACTIVE
kernel add route 192.168.91.0/24
if_fsm: event UP resulted in action START and changing state for interface em1
from DOWN to ACTIVE
kernel add route 192.168.91.0/24
if_fsm: interface lo1, event UP not expected in state LOOP
kernel add route 192.168.92.0/24
kernel add route 192.168.92.0/24
kernel add route 192.168.93.0/24
kernel add route 192.168.93.0/24
kernel add route 192.168.94.0/24
kernel add route 192.168.94.0/24
kernel add route 192.168.95.0/24
kernel add route 192.168.95.0/24
kernel add route 192.168.100.2/32
kernel add route 192.168.100.4/32
nbr_fsm: event HELLO RECEIVED resulted in action START INACTIVITY TIMER and
changing state for neighbor ID 192.168.100.1 from DOWN to PRESENT
send_init: neighbor ID 192.168.100.1
nbr_fsm: event INIT SENT resulted in action NOTHING and changing state for
neighbor ID 192.168.100.1 from PRESENT to OPENSENT
recv_notification: neighbor ID 192.168.100.1
recieved notification from neighbor 192.168.100.1: Session Rejected, No Hello
session_close: closing session with nbr ID 192.168.100.1
nbr_fsm: event SESSION CLOSE resulted in action CLOSE SESSION and changing
state for neighbor ID 192.168.100.1 from OPENSENT to PRESENT
nbr_fsm: event HELLO RECEIVED resulted in action START INACTIVITY TIMER and
changing state for neighbor ID 192.168.100.4 from DOWN to PRESENT
nbr_fsm: event HELLO RECEIVED resulted in action START INACTIVITY TIMER and
changing state for neighbor ID 192.168.100.3 from DOWN to PRESENT
nbr_fsm: event SESSION UP resulted in action START NEIGHBOR SESSION and
changing state for neighbor ID 192.168.100.4 from PRESENT to INITIALIZED
recv_init: neighbor ID 192.168.100.4
send_init: neighbor ID 192.168.100.4
nbr_fsm: event INIT RECEIVED resulted in action SEND INIT and changing state
for neighbor ID 192.168.100.4 from INITIALIZED to OPENREC
send_address: neighbor ID 192.168.100.4
nbr_fsm: event KEEPALIVE RECEIVED resulted in action START KEEPALIVE TIMER and
changing state for neighbor ID 192.168.100.4 from OPENREC to OPERATIONAL
recv_address: neighbor ID 192.168.100.4
lde_address_add: added 192.168.94.4
lde_address_add: added 192.168.95.4
lde_address_add: added 192.168.100.4
label mapping from nbr 192.168.100.4, FEC 192.168.100.4/32, label 3
label mapping from nbr 192.168.100.4, FEC 192.168.92.0/24, label 299776
label mapping from nbr 192.168.100.4, FEC 192.168.93.0/24, label 299792
label mapping from nbr 192.168.100.4, FEC 192.168.100.1/32, label 299808
label mapping from nbr 192.168.100.4, FEC 192.168.100.2/32, label 299824
label mapping from nbr 192.168.100.4, FEC 0.0.0.0/0, label 299840
label mapping from nbr 192.168.100.4, FEC 192.168.100.3/32, label 299856
label mapping from nbr 192.168.100.4, FEC 192.168.91.0/24, label 300016
nbr_fsm: event SESSION UP resulted in action START NEIGHBOR SESSION and
changing state for neighbor ID 192.168.100.3 from PRESENT to INITIALIZED
recv_init: neighbor ID 192.168.100.3
send_init: neighbor ID 192.168.100.3
nbr_fsm: event INIT RECEIVED resulted in action SEND INIT and changing state
for neighbor ID 192.168.100.3 from INITIALIZED to OPENREC
send_address: neighbor ID 192.168.100.3
nbr_fsm: event KEEPALIVE RECEIVED resulted in action START KEEPALIVE TIMER and
changing state for neighbor ID 192.168.100.3 from OPENREC to OPERATIONAL
recv_address: neighbor ID 192.168.100.3
lde_address_add: added 192.168.92.3
lde_address_add: added 192.168.93.3
lde_address_add: added 192.168.95.3
label mapping from nbr 192.168.100.3, FEC 192.168.100.3/32, label 3
label mapping from nbr 192.168.100.3, FEC 192.168.100.4/32, label 300848
label mapping from nbr 192.168.100.3, FEC 0.0.0.0/0, label 300864
label mapping from nbr 192.168.100.3, FEC 192.168.100.1/32, label 300896
label mapping from nbr 192.168.100.3, FEC 192.168.94.0/24, label 300944
label mapping from nbr 192.168.100.3, FEC 192.168.100.2/32, label 300992
label mapping from nbr 192.168.100.3, FEC 192.168.91.0/24, label 301024
nbr_idtimer: neighbor ID 192.168.100.1 peerid 3
send_init: neighbor ID 192.168.100.1
nbr_fsm: event INIT SENT resulted in action NOTHING and changing state for
neighbor ID 192.168.100.1 from PRESENT to OPENSENT
recv_notification: neighbor ID 192.168.100.1
recieved notification from neighbor 192.168.100.1: Session Rejected, No Hello
session_close: closing session with nbr ID 192.168.100.1
nbr_fsm: event SESSION CLOSE resulted in action CLOSE SESSION and changing
state for neighbor ID 192.168.100.1 from OPENSENT to PRESENT
nbr_idtimer: neighbor ID 192.168.100.1 peerid 3
send_init: neighbor ID 192.168.100.1
nbr_fsm: event INIT SENT resulted in action NOTHING and changing state for
neighbor ID 192.168.100.1 from PRESENT to OPENSENT
recv_notification: neighbor ID 192.168.100.1
recieved notification from neighbor 192.168.100.1: Session Rejected, No Hello
session_close: closing session with nbr ID 192.168.100.1
nbr_fsm: event SESSION CLOSE resulted in action CLOSE SESSION and changing
state for neighbor ID 192.168.100.1 from OPENSENT to PRESENT
nbr_idtimer: neighbor ID 192.168.100.1 peerid 3
send_init: neighbor ID 192.168.100.1
nbr_fsm: event INIT SENT resulted in action NOTHING and changing state for
neighbor ID 192.168.100.1 from PRESENT to OPENSENT
recv_notification: neighbor ID 192.168.100.1
recieved notification from neighbor 192.168.100.1: Session Rejected, No Hello
session_close: closing session with nbr ID 192.168.100.1
nbr_fsm: event SESSION CLOSE resulted in action CLOSE SESSION and changing
state for neighbor ID 192.168.100.1 from OPENSENT to PRESENT


On Jan 9, 2011, at 4:45 PM, Claudio Jeker wrote:

> On Sat, Jan 08, 2011 at 08:04:33PM +0100, Marcel Wiget wrote:
>> On Jan 8, 2011, at 4:20 PM, Claudio Jeker wrote:
>>
>>> Commited the diff. I guess there is a bit more needed so that we handle
>>> various unknown TLVs correctly in hello and initializaion. I hope I can
>>> provide a diff for this soon. Btw. I would be interested in the ldpd -dv
>>> output of the failures you get when the JUNOS has RFC 3479 enabled or
when
>>> a different transport addr is used.
>>
>> Thanks! Without 'set protocols ldp graceful-restart helper-disable' on
junos,
>> I get the following output from ldpd -dv. Packet dump of the LDP
>> initialization message and openbsd's response further down:
>>
>
> Thanks for all the info. Can you try the following diff?
> This should allow unkown TLVs in hello and initialization messages.
> This should signal the JUNOS neighbor that it needs to disable FT.
>
> --
> :wq Claudio
>
> Index: hello.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ldpd/hello.c,v
> retrieving revision 1.8
> diff -u -p -r1.8 hello.c
> --- hello.c   8 Jan 2011 14:50:29 -0000       1.8
> +++ hello.c   9 Jan 2011 14:55:12 -0000
> @@ -202,32 +202,37 @@ int
> tlv_decode_opt_hello_prms(char *buf, u_int16_t len, struct in_addr *addr,
>     u_int32_t *conf_number)
> {
> -     struct hello_opt_parms_tlv      tlv;
> -     int                             cons = 0;
> +     struct tlv      tlv;
> +     int             cons = 0;
> +     u_int16_t       tlv_len;
>
>       bzero(addr, sizeof(*addr));
>       *conf_number = 0;
>
>       while (len >= sizeof(tlv)) {
>               bcopy(buf, &tlv, sizeof(tlv));
> -
> -             if (ntohs(tlv.length) < sizeof(u_int32_t))
> -                     return (-1);
> -
> +             tlv_len = ntohs(tlv.length);
>               switch (ntohs(tlv.type)) {
>               case TLV_TYPE_IPV4TRANSADDR:
> -                     addr->s_addr = tlv.value;
> +                     if (tlv_len < sizeof(u_int32_t))
> +                             return (-1);
> +                     bcopy(buf + TLV_HDR_LEN, addr, sizeof(u_int32_t));
>                       break;
>               case TLV_TYPE_CONFIG:
> -                     *conf_number = ntohl(tlv.value);
> +                     if (tlv_len < sizeof(u_int32_t))
> +                             return (-1);
> +                     bcopy(buf + TLV_HDR_LEN, conf_number,
> +                         sizeof(u_int32_t));
>                       break;
>               default:
> -                     return (-1);
> +                     /* if unknown flag set, ignore TLV */
> +                     if (!(ntohs(tlv.type) & UNKNOWN_FLAG))
> +                             return (-1);
> +                     break;
>               }
> -
> -             len -= sizeof(tlv);
> -             buf += sizeof(tlv);
> -             cons += sizeof(tlv);
> +             buf += TLV_HDR_LEN + tlv_len;
> +             len -= TLV_HDR_LEN + tlv_len;
> +             cons += TLV_HDR_LEN + tlv_len;
>       }
>
>       return (cons);
> Index: init.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ldpd/init.c,v
> retrieving revision 1.6
> diff -u -p -r1.6 init.c
> --- init.c    4 Nov 2010 09:52:16 -0000       1.6
> +++ init.c    9 Jan 2011 14:55:35 -0000
> @@ -38,6 +38,7 @@
> #include "ldpe.h"
>
> int   gen_init_prms_tlv(struct ibuf *, struct nbr *, u_int16_t);
> +int  tlv_decode_opt_init_prms(char *, u_int16_t);
>
> void
> send_init(struct nbr *nbr)
> @@ -88,12 +89,19 @@ recv_init(struct nbr *nbr, char *buf, u_
>       bcopy(buf, &sess, sizeof(sess));
>
>       if (ntohs(sess.length) != SESS_PRMS_SIZE - TLV_HDR_LEN ||
> -         ntohs(sess.length) != len - TLV_HDR_LEN) {
> +         ntohs(sess.length) > len - TLV_HDR_LEN) {
>               session_shutdown(nbr, S_BAD_TLV_LEN, init.msgid, init.type);
>               return (-1);
>       }
>
> -     /* ATM and Frame Relay optional attributes not supported */
> +     buf += SESS_PRMS_SIZE;
> +     len -= SESS_PRMS_SIZE;
> +
> +     /* just ignore all optional TLVs for now */
> +     if (tlv_decode_opt_init_prms(buf, len) == -1) {
> +             session_shutdown(nbr, S_BAD_TLV_VAL, init.msgid, init.type);
> +             return (-1);
> +     }
>
>       if (nbr->iface->keepalive < ntohs(sess.keepalive_time))
>               nbr->keepalive = nbr->iface->keepalive;
> @@ -126,4 +134,35 @@ gen_init_prms_tlv(struct ibuf *buf, stru
>       parms.lspace_id = 0;
>
>       return (ibuf_add(buf, &parms, SESS_PRMS_SIZE));
> +}
> +
> +int
> +tlv_decode_opt_init_prms(char *buf, u_int16_t len)
> +{
> +     struct tlv      tlv;
> +     int             cons = 0;
> +     u_int16_t       tlv_len;
> +
> +      while (len >= sizeof(tlv)) {
> +             bcopy(buf, &tlv, sizeof(tlv));
> +             tlv_len = ntohs(tlv.length);
> +             switch (ntohs(tlv.type)) {
> +             case TLV_TYPE_ATMSESSIONPAR:
> +                     log_warnx("ATM session parameter present");
> +                     return (-1);
> +             case TLV_TYPE_FRSESSION:
> +                     log_warnx("FR session parameter present");
> +                     return (-1);
> +             default:
> +                     /* if unknown flag set, ignore TLV */
> +                     if (!(ntohs(tlv.type) & UNKNOWN_FLAG))
> +                             return (-1);
> +                     break;
> +             }
> +             buf += TLV_HDR_LEN + tlv_len;
> +             len -= TLV_HDR_LEN + tlv_len;
> +             cons += TLV_HDR_LEN + tlv_len;
> +     }
> +
> +     return (cons);
> }
> Index: labelmapping.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ldpd/labelmapping.c,v
> retrieving revision 1.18
> diff -u -p -r1.18 labelmapping.c
> --- labelmapping.c    31 Dec 2010 21:22:42 -0000      1.18
> +++ labelmapping.c    9 Jan 2011 14:33:51 -0000
> @@ -93,7 +93,7 @@ int
> recv_labelmapping(struct nbr *nbr, char *buf, u_int16_t len)
> {
>       struct ldp_msg          lm;
> -     struct fec_tlv          ft;
> +     struct tlv              ft;
>       struct map              map;
>       u_int32_t               label;
>       int                     feclen, lbllen, tlen;
> @@ -202,7 +202,7 @@ int
> recv_labelrequest(struct nbr *nbr, char *buf, u_int16_t len)
> {
>       struct ldp_msg  lr;
> -     struct fec_tlv  ft;
> +     struct tlv      ft;
>       struct map      map;
>       int             feclen, tlen;
>       u_int8_t        addr_type;
> @@ -308,7 +308,7 @@ recv_labelwithdraw(struct nbr *nbr, char
> {
>       struct map      map;
>       struct ldp_msg  lw;
> -     struct fec_tlv  ft;
> +     struct tlv      ft;
>       u_int32_t       label = NO_LABEL;
>       int             feclen, tlen, numfec = 0;
>       u_int8_t        addr_type;
> @@ -449,7 +449,7 @@ recv_labelrelease(struct nbr *nbr, char
> {
>       struct map      map;
>       struct ldp_msg  lr;
> -     struct fec_tlv  ft;
> +     struct tlv      ft;
>       u_int32_t       label = NO_LABEL;
>       int             feclen, tlen, numfec = 0;
>       u_int8_t        addr_type;
> @@ -568,7 +568,7 @@ recv_labelabortreq(struct nbr *nbr, char
> {
>       struct map      map;
>       struct ldp_msg  la;
> -     struct fec_tlv  ft;
> +     struct tlv      ft;
>       int             feclen, tlen;
>       u_int8_t        addr_type;
>
> @@ -707,7 +707,7 @@ tlv_decode_reqid(char *buf, u_int16_t le
> void
> gen_fec_tlv(struct ibuf *buf, struct in_addr prefix, u_int8_t prefixlen)
> {
> -     struct fec_tlv  ft;
> +     struct tlv      ft;
>       u_int8_t        type;
>       u_int16_t       family;
>       u_int8_t        len;
> Index: ldp.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ldpd/ldp.h,v
> retrieving revision 1.7
> diff -u -p -r1.7 ldp.h
> --- ldp.h     4 Nov 2010 09:52:16 -0000       1.7
> +++ ldp.h     9 Jan 2011 14:34:20 -0000
> @@ -97,6 +97,12 @@ struct ldp_hdr {
> #define       INFINITE_HOLDTIME       0xffff
>
> /* TLV record */
> +struct tlv {
> +     u_int16_t       type;
> +     u_int16_t       length;
> +};
> +#define      TLV_HDR_LEN             4
> +
> struct ldp_msg {
>       u_int16_t       type;
>       u_int16_t       length;
> @@ -106,7 +112,6 @@ struct ldp_msg {
> } __packed;
>
> #define LDP_MSG_LEN           8
> -#define      TLV_HDR_LEN             4
>
> #define       UNKNOWN_FLAGS_MASK      0xc000
> #define       UNKNOWN_FLAG            0x8000
> @@ -189,12 +194,6 @@ struct address_list_tlv {
> #define       ADDR_IPV4               0x1
> #define       ADDR_IPV6               0x2
>
> -struct fec_tlv {
> -     u_int16_t       type;
> -     u_int16_t       length;
> -     /* fec elm entries */
> -};
> -
> /* This struct is badly aligned so use two 32 bit fields */
> struct fec_elm {
>       u_int32_t       hdr;
> @@ -202,10 +201,8 @@ struct fec_elm {
> };
>
> #define FEC_ELM_MIN_LEN               4
> -
> #define       FEC_WILDCARD            0x01
> #define       FEC_PREFIX              0x02
> -
> #define       FEC_IPV4                0x0001
>
> struct label_tlv {
> @@ -223,12 +220,6 @@ struct reqid_tlv {
> };
>
> #define REQID_TLV_LEN         8
> -
> -struct hello_opt_parms_tlv {
> -     u_int16_t       type;
> -     u_int16_t       length;
> -     u_int32_t       value;
> -};
>
> #define       NO_LABEL                UINT_MAX

Reply via email to