ok

Claudio Jeker([email protected]) on 2021.07.13 15:37:36 +0200:
> This diff adds support to read MRT files using the new introduced _ADDPATH
> types as defined in RFC8050. I also started adding MRT support to bgpd but
> that depends on ADD-PATH itself.
> 
> There are a few gotchas, especially the MRT_DUMP_V2 RIB_GENERIC_ADDPATH
> handling is different from all other RIB entry handling. This is a major
> pain point for bgpd less so for the bgpctl parser.
> 
> Some MRT update dumps that can be downloaded and use ADDPATH do actually
> use the BGP4MP_MESSAGE _ADDPATH variant for non-addpath enabled sessions.
> The update messages can not be parsed because the NLRI encoding is incorrect.
> 
> I tested with a few RIB and UPDATE dumps from RIS, route-views and other
> open collectors and it works for me.
> -- 
> :wq Claudio
> 
> Index: usr.sbin/bgpctl/bgpctl.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
> retrieving revision 1.269
> diff -u -p -r1.269 bgpctl.c
> --- usr.sbin/bgpctl/bgpctl.c  16 Jun 2021 16:24:11 -0000      1.269
> +++ usr.sbin/bgpctl/bgpctl.c  13 Jul 2021 13:20:51 -0000
> @@ -470,7 +470,7 @@ show(struct imsg *imsg, struct parse_res
>                       warnx("bad IMSG_CTL_SHOW_RIB_ATTR received");
>                       break;
>               }
> -             output->attr(imsg->data, ilen, res->flags);
> +             output->attr(imsg->data, ilen, res->flags, 0);
>               break;
>       case IMSG_CTL_SHOW_RIB_MEM:
>               if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(stats))
> @@ -1150,6 +1150,10 @@ show_mrt_dump(struct mrt_rib *mr, struct
>               ctl.local_pref = mre->local_pref;
>               ctl.med = mre->med;
>               /* weight is not part of the mrt dump so it can't be set */
> +             if (mr->add_path) {
> +                     ctl.flags |= F_PREF_PATH_ID;
> +                     ctl.path_id = mre->path_id;
> +             }
>  
>               if (mre->peer_idx < mp->npeers) {
>                       ctl.remote_addr = mp->peers[mre->peer_idx].addr;
> @@ -1195,7 +1199,7 @@ show_mrt_dump(struct mrt_rib *mr, struct
>               if (req->flags & F_CTL_DETAIL) {
>                       for (j = 0; j < mre->nattrs; j++)
>                               output->attr(mre->attrs[j].attr,
> -                                 mre->attrs[j].attr_len, req->flags);
> +                                 mre->attrs[j].attr_len, req->flags, 0);
>               }
>       }
>  }
> @@ -1211,6 +1215,10 @@ network_mrt_dump(struct mrt_rib *mr, str
>       time_t                           now;
>       u_int16_t                        i, j;
>  
> +     /* can't announce more than one path so ignore add-path */
> +     if (mr->add_path)
> +             return;
> +
>       now = time(NULL);
>       for (i = 0; i < mr->nentries; i++) {
>               mre = &mr->entries[i];
> @@ -1586,10 +1594,11 @@ show_mrt_notification(u_char *p, u_int16
>  
>  /* XXX this function does not handle JSON output */
>  static void
> -show_mrt_update(u_char *p, u_int16_t len, int reqflags)
> +show_mrt_update(u_char *p, u_int16_t len, int reqflags, int addpath)
>  {
>       struct bgpd_addr prefix;
>       int pos;
> +     u_int32_t pathid;
>       u_int16_t wlen, alen;
>       u_int8_t prefixlen;
>  
> @@ -1609,12 +1618,25 @@ show_mrt_update(u_char *p, u_int16_t len
>       if (wlen > 0) {
>               printf("\n     Withdrawn prefixes:");
>               while (wlen > 0) {
> +                     if (addpath) {
> +                             if (wlen <= sizeof(pathid)) {
> +                                     printf("bad withdraw prefix");
> +                                     return;
> +                             }
> +                             memcpy(&pathid, p, sizeof(pathid));
> +                             pathid = ntohl(pathid);
> +                             p += sizeof(pathid);
> +                             len -= sizeof(pathid);
> +                             wlen -= sizeof(pathid);
> +                     }
>                       if ((pos = nlri_get_prefix(p, wlen, &prefix,
>                           &prefixlen)) == -1) {
>                               printf("bad withdraw prefix");
>                               return;
>                       }
>                       printf(" %s/%u", log_addr(&prefix), prefixlen);
> +                     if (addpath)
> +                             printf(" path-id %u", pathid);
>                       p += pos;
>                       len -= pos;
>                       wlen -= pos;
> @@ -1655,7 +1677,7 @@ show_mrt_update(u_char *p, u_int16_t len
>                       attrlen += 1 + 2;
>               }
>  
> -             output->attr(p, attrlen, reqflags);
> +             output->attr(p, attrlen, reqflags, addpath);
>               p += attrlen;
>               alen -= attrlen;
>               len -= attrlen;
> @@ -1664,12 +1686,24 @@ show_mrt_update(u_char *p, u_int16_t len
>       if (len > 0) {
>               printf("    NLRI prefixes:");
>               while (len > 0) {
> +                     if (addpath) {
> +                             if (len <= sizeof(pathid)) {
> +                                     printf(" bad nlri prefix: pathid, len 
> %d", len);
> +                                     return;
> +                             }
> +                             memcpy(&pathid, p, sizeof(pathid));
> +                             pathid = ntohl(pathid);
> +                             p += sizeof(pathid);
> +                             len -= sizeof(pathid);
> +                     }
>                       if ((pos = nlri_get_prefix(p, len, &prefix,
>                           &prefixlen)) == -1) {
> -                             printf("bad withdraw prefix");
> +                             printf(" bad nlri prefix");
>                               return;
>                       }
>                       printf(" %s/%u", log_addr(&prefix), prefixlen);
> +                     if (addpath)
> +                             printf(" path-id %u", pathid);
>                       p += pos;
>                       len -= pos;
>               }
> @@ -1739,7 +1773,8 @@ show_mrt_msg(struct mrt_bgp_msg *mm, voi
>                       printf("illegal length: %u byte\n", len);
>                       return;
>               }
> -             show_mrt_update(p, len - MSGSIZE_HEADER, req->flags);
> +             show_mrt_update(p, len - MSGSIZE_HEADER, req->flags,
> +                 mm->add_path);
>               break;
>       case KEEPALIVE:
>               printf("%s ", msgtypenames[type]);
> Index: usr.sbin/bgpctl/bgpctl.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.h,v
> retrieving revision 1.11
> diff -u -p -r1.11 bgpctl.h
> --- usr.sbin/bgpctl/bgpctl.h  3 May 2021 14:01:56 -0000       1.11
> +++ usr.sbin/bgpctl/bgpctl.h  13 Jul 2021 13:20:51 -0000
> @@ -24,7 +24,7 @@ struct output {
>       void    (*fib_table)(struct ktable *);
>       void    (*nexthop)(struct ctl_show_nexthop *);
>       void    (*interface)(struct ctl_show_interface *);
> -     void    (*attr)(u_char *, size_t, int);
> +     void    (*attr)(u_char *, size_t, int, int);
>       void    (*communities)(u_char *, size_t, struct parse_result *);
>       void    (*rib)(struct ctl_show_rib *, u_char *, size_t,
>                   struct parse_result *);
> Index: usr.sbin/bgpctl/mrtparser.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpctl/mrtparser.c,v
> retrieving revision 1.14
> diff -u -p -r1.14 mrtparser.c
> --- usr.sbin/bgpctl/mrtparser.c       18 Jan 2021 12:16:09 -0000      1.14
> +++ usr.sbin/bgpctl/mrtparser.c       13 Jul 2021 13:20:51 -0000
> @@ -103,8 +103,10 @@ mrt_parse(int fd, struct mrt_parser *p, 
>       struct mrt_bgp_state    *s;
>       struct mrt_bgp_msg      *m;
>       void                    *msg;
> +     int                      addpath;
>  
>       while ((msg = mrt_read_msg(fd, &h))) {
> +             addpath = 0;
>               switch (ntohs(h.type)) {
>               case MSG_NULL:
>               case MSG_START:
> @@ -163,6 +165,11 @@ mrt_parse(int fd, struct mrt_parser *p, 
>                       case MRT_DUMP_V2_RIB_IPV6_UNICAST:
>                       case MRT_DUMP_V2_RIB_IPV6_MULTICAST:
>                       case MRT_DUMP_V2_RIB_GENERIC:
> +                     case MRT_DUMP_V2_RIB_IPV4_UNICAST_ADDPATH:
> +                     case MRT_DUMP_V2_RIB_IPV4_MULTICAST_ADDPATH:
> +                     case MRT_DUMP_V2_RIB_IPV6_UNICAST_ADDPATH:
> +                     case MRT_DUMP_V2_RIB_IPV6_MULTICAST_ADDPATH:
> +                     case MRT_DUMP_V2_RIB_GENERIC_ADDPATH:
>                               if (p->dump == NULL)
>                                       break;
>                               r = mrt_parse_v2_rib(&h, msg, verbose);
> @@ -194,6 +201,10 @@ mrt_parse(int fd, struct mrt_parser *p, 
>                       case BGP4MP_MESSAGE_AS4:
>                       case BGP4MP_MESSAGE_LOCAL:
>                       case BGP4MP_MESSAGE_AS4_LOCAL:
> +                     case BGP4MP_MESSAGE_ADDPATH:
> +                     case BGP4MP_MESSAGE_AS4_ADDPATH:
> +                     case BGP4MP_MESSAGE_LOCAL_ADDPATH:
> +                     case BGP4MP_MESSAGE_AS4_LOCAL_ADDPATH:
>                               if ((m = mrt_parse_msg(&h, msg, verbose))) {
>                                       if (p->message)
>                                               p->message(m, p->arg);
> @@ -362,10 +373,10 @@ mrt_parse_v2_rib(struct mrt_hdr *hdr, vo
>       struct mrt_rib  *r;
>       u_int8_t        *b = msg;
>       u_int           len = ntohl(hdr->length);
> -     u_int32_t       snum;
> +     u_int32_t       snum, path_id = 0;
>       u_int16_t       cnt, i, afi;
>       u_int8_t        safi, aid;
> -     int             ret;
> +     int             ret, addpath = 0;
>  
>       if (len < sizeof(snum) + 1)
>               return NULL;
> @@ -381,6 +392,10 @@ mrt_parse_v2_rib(struct mrt_hdr *hdr, vo
>       r->seqnum = ntohl(snum);
>  
>       switch (ntohs(hdr->subtype)) {
> +     case MRT_DUMP_V2_RIB_IPV4_UNICAST_ADDPATH:
> +     case MRT_DUMP_V2_RIB_IPV4_MULTICAST_ADDPATH:
> +             r->add_path = 1;
> +             /* FALLTHROUGH */
>       case MRT_DUMP_V2_RIB_IPV4_UNICAST:
>       case MRT_DUMP_V2_RIB_IPV4_MULTICAST:
>               /* prefix */
> @@ -389,6 +404,10 @@ mrt_parse_v2_rib(struct mrt_hdr *hdr, vo
>               if (ret == 1)
>                       goto fail;
>               break;
> +     case MRT_DUMP_V2_RIB_IPV6_UNICAST_ADDPATH:
> +     case MRT_DUMP_V2_RIB_IPV6_MULTICAST_ADDPATH:
> +             r->add_path = 1;
> +             /* FALLTHROUGH */
>       case MRT_DUMP_V2_RIB_IPV6_UNICAST:
>       case MRT_DUMP_V2_RIB_IPV6_MULTICAST:
>               /* prefix */
> @@ -397,8 +416,13 @@ mrt_parse_v2_rib(struct mrt_hdr *hdr, vo
>               if (ret == 1)
>                       goto fail;
>               break;
> +     case MRT_DUMP_V2_RIB_GENERIC_ADDPATH:
> +             r->add_path = 1;
> +             /* FALLTHROUGH */
>       case MRT_DUMP_V2_RIB_GENERIC:
>               /* fetch AFI/SAFI pair */
> +             if (len < 3)
> +                     goto fail;
>               memcpy(&afi, b, sizeof(afi));
>               b += sizeof(afi);
>               len -= sizeof(afi);
> @@ -410,6 +434,16 @@ mrt_parse_v2_rib(struct mrt_hdr *hdr, vo
>               if ((aid = mrt_afi2aid(afi, safi, verbose)) == AID_UNSPEC)
>                       goto fail;
>               
> +             /* RFC8050 handling for add-path */
> +             if (r->add_path) {
> +                     if (len < sizeof(path_id))
> +                             goto fail;
> +                     memcpy(&path_id, b, sizeof(path_id));
> +                     b += sizeof(path_id);
> +                     len -= sizeof(path_id);
> +                     path_id = ntohl(path_id);
> +             }
> +
>               /* prefix */
>               ret = mrt_extract_prefix(b, len, aid, &r->prefix,
>                   &r->prefixlen, verbose);
> @@ -453,6 +487,19 @@ mrt_parse_v2_rib(struct mrt_hdr *hdr, vo
>               len -= sizeof(otm);
>               entries[i].originated = ntohl(otm);
>  
> +             /* RFC8050 handling for add-path */
> +             if (r->add_path &&
> +                 ntohs(hdr->subtype) != MRT_DUMP_V2_RIB_GENERIC_ADDPATH) {
> +                     if (len < sizeof(path_id) + sizeof(alen))
> +                             goto fail;
> +                     addpath = 0;
> +                     memcpy(&path_id, b, sizeof(path_id));
> +                     b += sizeof(path_id);
> +                     len -= sizeof(path_id);
> +                     path_id = ntohl(path_id);
> +             }
> +             entries[i].path_id = path_id;
> +
>               /* attr_len */
>               memcpy(&alen, b, sizeof(alen));
>               b += sizeof(alen);
> @@ -1141,7 +1188,7 @@ mrt_parse_msg(struct mrt_hdr *hdr, void 
>       u_int                    len = ntohl(hdr->length);
>       u_int32_t                sas, das, usec;
>       u_int16_t                tmp16, afi;
> -     int                      r;
> +     int                      r, addpath = 0;
>       u_int8_t                 aid;
>  
>       t.tv_sec = ntohl(hdr->timestamp);
> @@ -1156,7 +1203,12 @@ mrt_parse_msg(struct mrt_hdr *hdr, void 
>       }
>  
>       switch (ntohs(hdr->subtype)) {
> +     case BGP4MP_MESSAGE_ADDPATH:
> +     case BGP4MP_MESSAGE_LOCAL_ADDPATH:
> +             addpath = 1;
> +             /* FALLTHROUGH */
>       case BGP4MP_MESSAGE:
> +     case BGP4MP_MESSAGE_LOCAL:
>               if (len < 8)
>                       return (0);
>               /* source as */
> @@ -1178,7 +1230,12 @@ mrt_parse_msg(struct mrt_hdr *hdr, void 
>               len -= sizeof(tmp16);
>               afi = ntohs(tmp16);
>               break;
> +     case BGP4MP_MESSAGE_AS4_ADDPATH:
> +     case BGP4MP_MESSAGE_AS4_LOCAL_ADDPATH:
> +             addpath = 1;
> +             /* FALLTHROUGH */
>       case BGP4MP_MESSAGE_AS4:
> +     case BGP4MP_MESSAGE_AS4_LOCAL:
>               if (len < 12)
>                       return (0);
>               /* source as */
> @@ -1213,6 +1270,7 @@ mrt_parse_msg(struct mrt_hdr *hdr, void 
>       m->time = t;
>       m->src_as = sas;
>       m->dst_as = das;
> +     m->add_path = addpath;
>  
>       if ((r = mrt_extract_addr(b, len, &m->src, aid)) == -1)
>               goto fail;
> Index: usr.sbin/bgpctl/mrtparser.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpctl/mrtparser.h,v
> retrieving revision 1.3
> diff -u -p -r1.3 mrtparser.h
> --- usr.sbin/bgpctl/mrtparser.h       25 Feb 2019 11:51:58 -0000      1.3
> +++ usr.sbin/bgpctl/mrtparser.h       13 Jul 2021 13:20:51 -0000
> @@ -43,6 +43,7 @@ struct mrt_rib_entry {
>       time_t           originated;
>       u_int32_t        local_pref;
>       u_int32_t        med;
> +     u_int32_t        path_id;
>       u_int16_t        peer_idx;
>       u_int16_t        aspath_len;
>       u_int16_t        nattrs;
> @@ -55,6 +56,7 @@ struct mrt_rib {
>       u_int32_t                seqnum;
>       u_int16_t                nentries;
>       u_int8_t                 prefixlen;
> +     u_int8_t                 add_path;
>  };
>  
>  /* data structures for the BGP4MP MESSAGE and STATE types */
> @@ -75,6 +77,7 @@ struct mrt_bgp_msg {
>       u_int32_t        src_as;
>       u_int32_t        dst_as;
>       u_int16_t        msg_len;
> +     u_int8_t         add_path;
>       void            *msg;
>  };
>  
> Index: usr.sbin/bgpctl/output.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpctl/output.c,v
> retrieving revision 1.17
> diff -u -p -r1.17 output.c
> --- usr.sbin/bgpctl/output.c  27 May 2021 08:29:07 -0000      1.17
> +++ usr.sbin/bgpctl/output.c  13 Jul 2021 13:20:51 -0000
> @@ -666,13 +666,13 @@ show_ext_community(u_char *data, u_int16
>  }
>  
>  static void
> -show_attr(u_char *data, size_t len, int reqflags)
> +show_attr(u_char *data, size_t len, int reqflags, int addpath)
>  {
>       u_char          *path;
>       struct in_addr   id;
>       struct bgpd_addr prefix;
>       char            *aspath;
> -     u_int32_t        as;
> +     u_int32_t        as, pathid;
>       u_int16_t        alen, ioff, short_as, afi;
>       u_int8_t         flags, type, safi, aid, prefixlen;
>       int              i, pos, e2, e4;
> @@ -851,6 +851,16 @@ show_attr(u_char *data, size_t len, int 
>               }
>  
>               while (alen > 0) {
> +                     if (addpath) {
> +                             if (alen <= sizeof(pathid)) {
> +                                     printf("bad nlri prefix");
> +                                     return;
> +                             }
> +                             memcpy(&pathid, data, sizeof(pathid));
> +                             pathid = ntohl(pathid);
> +                             data += sizeof(pathid);
> +                             alen -= sizeof(pathid);
> +                     }
>                       switch (aid) {
>                       case AID_INET6:
>                               pos = nlri_get_prefix6(data, alen, &prefix,
> @@ -873,6 +883,8 @@ show_attr(u_char *data, size_t len, int 
>                               break;
>                       }
>                       printf(" %s/%u", log_addr(&prefix), prefixlen);
> +                     if (addpath)
> +                             printf(" path-id %u", pathid);
>                       data += pos;
>                       alen -= pos;
>               }
> @@ -940,7 +952,10 @@ show_rib_detail(struct ctl_show_rib *r, 
>       printf("(via %s) Neighbor %s (", log_addr(&r->true_nexthop), s);
>       free(s);
>       id.s_addr = htonl(r->remote_id);
> -     printf("%s)%c", inet_ntoa(id), EOL0(flag0));
> +
> +     if (r->flags & F_PREF_PATH_ID)
> +             printf("%s) Path-Id: %u%c", inet_ntoa(id), r->path_id,
> +                 EOL0(flag0));
>  
>       printf("    Origin %s, metric %u, localpref %u, weight %u, ovs %s, ",
>           fmt_origin(r->origin, 0), r->med, r->local_pref, r->weight,
> Index: usr.sbin/bgpctl/output_json.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpctl/output_json.c,v
> retrieving revision 1.11
> diff -u -p -r1.11 output_json.c
> --- usr.sbin/bgpctl/output_json.c     27 May 2021 08:29:07 -0000      1.11
> +++ usr.sbin/bgpctl/output_json.c     13 Jul 2021 13:20:51 -0000
> @@ -586,13 +586,13 @@ json_do_ext_community(u_char *data, uint
>  }
>  
>  static void
> -json_attr(u_char *data, size_t len, int reqflags)
> +json_attr(u_char *data, size_t len, int reqflags, int addpath)
>  {
>       struct bgpd_addr prefix;
>       struct in_addr id;
>       char *aspath;
>       u_char *path;
> -     uint32_t as;
> +     uint32_t as, pathid;
>       uint16_t alen, afi, off, short_as;
>       uint8_t flags, type, safi, aid, prefixlen;
>       int e4, e2, pos;
> @@ -783,6 +783,17 @@ bad_len:
>  
>               json_do_array("NLRI");
>               while (alen > 0) {
> +                     json_do_object("prefix");
> +                     if (addpath) {
> +                             if (alen <= sizeof(pathid)) {
> +                                     json_do_printf("error", "bad path-id");
> +                                     break;
> +                             }
> +                             memcpy(&pathid, data, sizeof(pathid));
> +                             pathid = ntohl(pathid);
> +                             data += sizeof(pathid);
> +                             alen -= sizeof(pathid);
> +                     }
>                       switch (aid) {
>                       case AID_INET6:
>                               pos = nlri_get_prefix6(data, alen, &prefix,
> @@ -808,9 +819,13 @@ bad_len:
>                       }
>                       json_do_printf("prefix", "%s/%u", log_addr(&prefix),
>                           prefixlen);
> +                     if (addpath)
> +                              json_do_uint("path_id", pathid);
>                       data += pos;
>                       alen -= pos;
> +                     json_do_end();
>               }
> +             json_do_end();
>               break;
>       case ATTR_EXT_COMMUNITIES:
>               json_do_ext_community(data, alen);
> @@ -854,6 +869,9 @@ json_rib(struct ctl_show_rib *r, u_char 
>       id.s_addr = htonl(r->remote_id);
>       json_do_printf("bgp_id", "%s", inet_ntoa(id));
>       json_do_end();
> +
> +     if (r->flags & F_PREF_PATH_ID)
> +             json_do_uint("path_id", r->path_id);
>  
>       /* flags */
>       json_do_bool("valid", r->flags & F_PREF_ELIGIBLE);
> Index: usr.sbin/bgpd/bgpd.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
> retrieving revision 1.415
> diff -u -p -r1.415 bgpd.h
> --- usr.sbin/bgpd/bgpd.h      17 Jun 2021 16:05:26 -0000      1.415
> +++ usr.sbin/bgpd/bgpd.h      13 Jul 2021 13:20:51 -0000
> @@ -791,6 +791,7 @@ struct ctl_neighbor {
>  #define      F_PREF_ANNOUNCE 0x08
>  #define      F_PREF_STALE    0x10
>  #define      F_PREF_INVALID  0x20
> +#define      F_PREF_PATH_ID  0x40
>  
>  struct ctl_show_rib {
>       struct bgpd_addr        true_nexthop;
> @@ -800,6 +801,7 @@ struct ctl_show_rib {
>       char                    descr[PEER_DESCR_LEN];
>       time_t                  age;
>       u_int32_t               remote_id;
> +     u_int32_t               path_id;
>       u_int32_t               local_pref;
>       u_int32_t               med;
>       u_int32_t               weight;
> Index: usr.sbin/bgpd/mrt.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/mrt.h,v
> retrieving revision 1.35
> diff -u -p -r1.35 mrt.h
> --- usr.sbin/bgpd/mrt.h       31 Dec 2019 15:09:40 -0000      1.35
> +++ usr.sbin/bgpd/mrt.h       13 Jul 2021 13:20:51 -0000
> @@ -84,7 +84,11 @@ enum MRT_BGP4MP_SUBTYPES {
>       BGP4MP_MESSAGE_AS4,     /* same as BGP4MP_MESSAGE with 4byte AS */
>       BGP4MP_STATE_CHANGE_AS4,
>       BGP4MP_MESSAGE_LOCAL,     /* same as BGP4MP_MESSAGE but for self */
> -     BGP4MP_MESSAGE_AS4_LOCAL  /* originated updates. Not implemented */
> +     BGP4MP_MESSAGE_AS4_LOCAL, /* originated updates. Not implemented */
> +     BGP4MP_MESSAGE_ADDPATH,   /* same as above but for add-path peers */
> +     BGP4MP_MESSAGE_AS4_ADDPATH,
> +     BGP4MP_MESSAGE_LOCAL_ADDPATH,
> +     BGP4MP_MESSAGE_AS4_LOCAL_ADDPATH,
>  };
>  
>  /* size of the BGP4MP headers without payload */
> @@ -178,7 +182,12 @@ enum MRT_DUMP_V2_SUBTYPES {
>       MRT_DUMP_V2_RIB_IPV4_MULTICAST=3,
>       MRT_DUMP_V2_RIB_IPV6_UNICAST=4,
>       MRT_DUMP_V2_RIB_IPV6_MULTICAST=5,
> -     MRT_DUMP_V2_RIB_GENERIC=6
> +     MRT_DUMP_V2_RIB_GENERIC=6,
> +     MRT_DUMP_V2_RIB_IPV4_UNICAST_ADDPATH=8,
> +     MRT_DUMP_V2_RIB_IPV4_MULTICAST_ADDPATH=9,
> +     MRT_DUMP_V2_RIB_IPV6_UNICAST_ADDPATH=10,
> +     MRT_DUMP_V2_RIB_IPV6_MULTICAST_ADDPATH=11,
> +     MRT_DUMP_V2_RIB_GENERIC_ADDPATH=12,
>  };
>  
>  /*
> @@ -228,7 +237,7 @@ enum MRT_DUMP_V2_SUBTYPES {
>   * |     #entry      | rib entries (variable)
>   * +--------+--------+--------+--------+
>   *
> - * The RIB_GENERIC subtype is needed for the less common AFI/SAFI pairs
> + * The RIB_GENERIC subtype is needed for the less common AFI/SAFI pairs.
>   *
>   * +--------+--------+--------+--------+
>   * |              seq_num              |
> @@ -249,6 +258,8 @@ enum MRT_DUMP_V2_SUBTYPES {
>   * +--------+--------+--------+--------+
>   * |          originated_time          |
>   * +--------+--------+--------+--------+
> + * [    path_id in _ADDPATH variants   ]
> + * +--------+--------+--------+--------+
>   * |    attr_len     |   bgp_attrs
>   * +--------+--------+--------+--------+
>   *      bgp_attrs (variable) ...
> @@ -257,6 +268,10 @@ enum MRT_DUMP_V2_SUBTYPES {
>   * Some BGP path attributes need special encoding:
>   *  - the AS_PATH attribute MUST be encoded as 4-Byte AS
>   *  - the MP_REACH_NLRI only consists of the nexthop len and nexthop address
> + *
> + * The non generic ADDPATH variants add the path-identifier between
> + * originated_time and attr_len. For RIB_GENERIC_ADDPATH the path_id should
> + * be part of the NLRI.
>   */
>  
>  /*
> 

Reply via email to