On 2016 Sep 14 (Wed) at 16:41:53 +0200 (+0200), Peter Hessler wrote:
:It is quite common to want to do a cross-protocol readvertisement from
:IGP->EGP.  We can add rtlabels in bgpd and ospfd, but only advertise
:in ospfd.
:
:This diff lets bgpd announce routes based on rtlabels.  The existing
:"cannot announce routes that point to localhost" and "cannot announce
:defaults" still apply.  Should they?
:
:OK?
:

Updated diff, with fixed man page.

I also talked to Henning, and we agree that the syntax should include
the the address family.

    network inet6 rtlabel "humppa"

OK?


Index: usr.sbin/bgpd/bgpd.conf.5
===================================================================
RCS file: /cvs/openbsd/src/usr.sbin/bgpd/bgpd.conf.5,v
retrieving revision 1.146
diff -u -p -u -p -r1.146 bgpd.conf.5
--- usr.sbin/bgpd/bgpd.conf.5   17 Aug 2016 08:14:40 -0000      1.146
+++ usr.sbin/bgpd/bgpd.conf.5   24 Sep 2016 06:57:33 -0000
@@ -268,6 +268,11 @@ Log received and sent updates.
 .Pq Ic inet Ns | Ns Ic inet6
 .Ic connected Op Ic set ...\&
 .Xc
+.It Xo
+.Ic network
+.Pq Ic inet Ns | Ns Ic inet6
+.Ic rtlabel Ar label Op Ic set ...\&
+.Xc
 Announce the specified network as belonging to our AS.
 If set to
 .Ic connected ,
@@ -275,6 +280,11 @@ routes to directly attached networks wil
 If set to
 .Ic static ,
 all static routes will be announced.
+If set to
+.Ic rtlabel ,
+routes with the specified
+.Ar label
+will be announced.
 .Bd -literal -offset indent
 network 192.168.7.0/24
 .Ed
Index: usr.sbin/bgpd/bgpd.h
===================================================================
RCS file: /cvs/openbsd/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.295
diff -u -p -u -p -r1.295 bgpd.h
--- usr.sbin/bgpd/bgpd.h        2 Sep 2016 14:00:29 -0000       1.295
+++ usr.sbin/bgpd/bgpd.h        24 Sep 2016 06:56:39 -0000
@@ -85,6 +85,7 @@
 #define        F_CTL_ADJ_IN            0x2000
 #define        F_CTL_ADJ_OUT           0x4000
 #define        F_CTL_ACTIVE            0x8000
+#define        F_RTLABEL               0x10000
 
 /*
  * Limit the number of control messages generated by the RDE and queued in
@@ -334,6 +335,7 @@ enum network_type {
        NETWORK_DEFAULT,
        NETWORK_STATIC,
        NETWORK_CONNECTED,
+       NETWORK_RTLABEL,
        NETWORK_MRTCLONE
 };
 
@@ -342,6 +344,7 @@ struct network_config {
        struct filter_set_head   attrset;
        struct rde_aspath       *asp;
        u_int                    rtableid;
+       u_int16_t                rtlabel;
        enum network_type        type;
        u_int8_t                 prefixlen;
        u_int8_t                 old;   /* used for reloading */
@@ -507,6 +510,7 @@ struct kroute_full {
        struct bgpd_addr        prefix;
        struct bgpd_addr        nexthop;
        char                    label[RTLABEL_LEN];
+       u_int16_t               labelid;
        u_int16_t               flags;
        u_short                 ifindex;
        u_int8_t                prefixlen;
Index: usr.sbin/bgpd/kroute.c
===================================================================
RCS file: /cvs/openbsd/src/usr.sbin/bgpd/kroute.c,v
retrieving revision 1.209
diff -u -p -u -p -r1.209 kroute.c
--- usr.sbin/bgpd/kroute.c      8 Apr 2016 12:27:05 -0000       1.209
+++ usr.sbin/bgpd/kroute.c      24 Sep 2016 06:56:39 -0000
@@ -1111,6 +1111,10 @@ kr_net_match(struct ktable *kt, struct k
                        if (kr->flags & F_CONNECTED)
                                return (xn);
                        break;
+               case NETWORK_RTLABEL:
+                       if (kr->labelid == xn->net.rtlabel)
+                               return (xn);
+                       break;
                case NETWORK_MRTCLONE:
                        /* can not happen */
                        break;
@@ -1143,6 +1147,10 @@ kr_net_match6(struct ktable *kt, struct 
                        if (kr6->flags & F_CONNECTED)
                                return (xn);
                        break;
+               case NETWORK_RTLABEL:
+                       if (kr6->labelid == xn->net.rtlabel)
+                               return (xn);
+                       break;
                case NETWORK_MRTCLONE:
                        /* can not happen */
                        break;
@@ -1269,6 +1277,7 @@ sendit:
        net.prefix.aid = AID_INET;
        net.prefix.v4.s_addr = kr->prefix.s_addr;
        net.prefixlen = kr->prefixlen;
+       net.rtlabel = kr->labelid;
        net.rtableid = kt->rtableid;
 
        return (send_network(type, &net, match ? &match->net.attrset : NULL));
@@ -1337,6 +1346,7 @@ sendit:
        net.prefix.aid = AID_INET6;
        memcpy(&net.prefix.v6, &kr6->prefix, sizeof(struct in6_addr));
        net.prefixlen = kr6->prefixlen;
+       net.rtlabel = kr6->labelid;
        net.rtableid = kt->rtableid;
 
        return (send_network(type, &net, match ? &match->net.attrset : NULL));
@@ -1392,6 +1402,7 @@ kr_tofull(struct kroute *kr)
        kf.nexthop.aid = AID_INET;
        kf.nexthop.v4.s_addr = kr->nexthop.s_addr;
        strlcpy(kf.label, rtlabel_id2name(kr->labelid), sizeof(kf.label));
+       kf.labelid = kr->labelid;
        kf.flags = kr->flags;
        kf.ifindex = kr->ifindex;
        kf.prefixlen = kr->prefixlen;
@@ -1412,6 +1423,7 @@ kr6_tofull(struct kroute6 *kr6)
        kf.nexthop.aid = AID_INET6;
        memcpy(&kf.nexthop.v6, &kr6->nexthop, sizeof(struct in6_addr));
        strlcpy(kf.label, rtlabel_id2name(kr6->labelid), sizeof(kf.label));
+       kf.labelid = kr6->labelid;
        kf.flags = kr6->flags;
        kf.ifindex = kr6->ifindex;
        kf.prefixlen = kr6->prefixlen;
@@ -2780,6 +2792,7 @@ fetchtable(struct ktable *kt, u_int8_t f
        struct sockaddr         *sa, *gw, *rti_info[RTAX_MAX];
        struct sockaddr_in      *sa_in;
        struct sockaddr_in6     *sa_in6;
+       struct sockaddr_rtlabel *label;
        struct kroute_node      *kr = NULL;
        struct kroute6_node     *kr6 = NULL;
 
@@ -2858,6 +2871,14 @@ fetchtable(struct ktable *kt, u_int8_t f
                        else
                                kr->r.prefixlen =
                                    prefixlen_classful(kr->r.prefix.s_addr);
+                       rtlabel_unref(kr->r.labelid);
+                       kr->r.labelid = 0;
+                       if ((label = (struct sockaddr_rtlabel *)
+                           rti_info[RTAX_LABEL]) != NULL) {
+                               kr->r.flags |= F_RTLABEL;
+                               kr->r.labelid =
+                                   rtlabel_name2id(label->sr_label);
+                       }
                        break;
                case AF_INET6:
                        if ((kr6 = calloc(1, sizeof(struct kroute6_node))) ==
@@ -2891,6 +2912,14 @@ fetchtable(struct ktable *kt, u_int8_t f
                                kr6->r.prefixlen = 128;
                        else
                                fatalx("INET6 route without netmask");
+                       rtlabel_unref(kr6->r.labelid);
+                       kr6->r.labelid = 0;
+                       if ((label = (struct sockaddr_rtlabel *)
+                           rti_info[RTAX_LABEL]) != NULL) {
+                               kr6->r.flags |= F_RTLABEL;
+                               kr6->r.labelid =
+                                   rtlabel_name2id(label->sr_label);
+                       }
                        break;
                default:
                        continue;
Index: usr.sbin/bgpd/parse.y
===================================================================
RCS file: /cvs/openbsd/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.288
diff -u -p -u -p -r1.288 parse.y
--- usr.sbin/bgpd/parse.y       21 Jun 2016 21:35:24 -0000      1.288
+++ usr.sbin/bgpd/parse.y       24 Sep 2016 06:56:39 -0000
@@ -674,6 +674,25 @@ network            : NETWORK prefix filter_set     {
 
                        TAILQ_INSERT_TAIL(netconf, n, entry);
                }
+               | NETWORK family RTLABEL STRING filter_set      {
+                       struct network  *n;
+
+                       if ((n = calloc(1, sizeof(struct network))) == NULL)
+                               fatal("new_network");
+                       if (afi2aid($2, SAFI_UNICAST, &n->net.prefix.aid) ==
+                           -1) {
+                               yyerror("unknown family");
+                               filterset_free($5);
+                               free($5);
+                               YYERROR;
+                       }
+                       n->net.type = NETWORK_RTLABEL;
+                       n->net.rtlabel = rtlabel_name2id($4);
+                       filterset_move($5, &n->net.attrset);
+                       free($5);
+
+                       TAILQ_INSERT_TAIL(netconf, n, entry);
+               }
                | NETWORK family nettype filter_set     {
                        struct network  *n;
 
Index: usr.sbin/bgpd/printconf.c
===================================================================
RCS file: /cvs/openbsd/src/usr.sbin/bgpd/printconf.c,v
retrieving revision 1.97
diff -u -p -u -p -r1.97 printconf.c
--- usr.sbin/bgpd/printconf.c   13 Jul 2016 20:07:38 -0000      1.97
+++ usr.sbin/bgpd/printconf.c   24 Sep 2016 06:56:39 -0000
@@ -336,6 +336,10 @@ print_network(struct network_config *n, 
        case NETWORK_CONNECTED:
                printf("%snetwork %s connected", c, print_af(n->prefix.aid));
                break;
+       case NETWORK_RTLABEL:
+               printf("%snetwork %s rtlabel \"%s\"", c,
+                   print_af(n->prefix.aid), rtlabel_id2name(n->rtlabel));
+               break;
        default:
                printf("%snetwork %s/%u", c, log_addr(&n->prefix),
                    n->prefixlen);


-- 
Personifiers Unite!  You have nothing to lose but Mr. Dignity!

Reply via email to