]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: cleanup blackhole support
authorDavid Lamparter <equinox@diac24.net>
Fri, 5 Feb 2010 03:31:56 +0000 (04:31 +0100)
committerDavid Lamparter <equinox@opensourcerouting.org>
Mon, 28 Aug 2017 03:07:51 +0000 (05:07 +0200)
blackhole support was horribly broken. cleanup by removing blackhole
stuff from ZEBRA_FLAG_*

introduces support for "prohibit" routes (Linux/netlink only)
also clean up blackhole options on "ip route" vty commands.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
14 files changed:
lib/nexthop.h
lib/zebra.h
zebra/kernel_socket.c
zebra/kernel_socket.h
zebra/rib.h
zebra/rt_netlink.c
zebra/rt_socket.c
zebra/zebra_fpm_netlink.c
zebra/zebra_fpm_protobuf.c
zebra/zebra_rib.c
zebra/zebra_static.c
zebra/zebra_static.h
zebra/zebra_vty.c
zebra/zserv.c

index 7cfba5c5b693a698c1b6f2e2d2c0731e052be5f2..781eb9341349eca685e1550409b937545bfcd205 100644 (file)
@@ -76,7 +76,10 @@ struct nexthop {
 #define NEXTHOP_FLAG_FILTERED   (1 << 5) /* rmap filtered, used by static only */
 
        /* Nexthop address */
-       union g_addr gate;
+       union {
+               union g_addr gate;
+               enum blackhole_type bh_type;
+       };
        union g_addr src;
        union g_addr rmap_src; /* Src is set via routemap */
 
index 6d64bbd670cd036a901d4da89ed5dd68fd1f2d73..fa5fa89f776116c2b1aff76c9241017a63222a5e 100644 (file)
@@ -404,13 +404,13 @@ extern const char *zserv_command_string(unsigned int command);
 /* Zebra message flags */
 #define ZEBRA_FLAG_INTERNAL           0x01
 #define ZEBRA_FLAG_SELFROUTE          0x02
-#define ZEBRA_FLAG_BLACKHOLE          0x04
 #define ZEBRA_FLAG_IBGP               0x08
 #define ZEBRA_FLAG_SELECTED           0x10
 #define ZEBRA_FLAG_STATIC             0x40
-#define ZEBRA_FLAG_REJECT             0x80
 #define ZEBRA_FLAG_SCOPE_LINK         0x100
 #define ZEBRA_FLAG_FIB_OVERRIDE       0x200
+/* ZEBRA_FLAG_BLACKHOLE was 0x04 */
+/* ZEBRA_FLAG_REJECT was 0x80 */
 
 /* Zebra FEC flags. */
 #define ZEBRA_FEC_REGISTER_LABEL_INDEX        0x1
index ee21e61fe726dae0cf8c6e4c6a6a9b841a2c4dca..7802a9d207d7f57c9b7a4148573116118dc621bf 100644 (file)
@@ -887,11 +887,15 @@ void rtm_read(struct rt_msghdr *rtm)
        if (flags & RTF_STATIC)
                SET_FLAG(zebra_flags, ZEBRA_FLAG_STATIC);
 
+       memset(&nh, 0, sizeof(nh));
        /* This is a reject or blackhole route */
-       if (flags & RTF_REJECT)
-               SET_FLAG(zebra_flags, ZEBRA_FLAG_REJECT);
-       if (flags & RTF_BLACKHOLE)
-               SET_FLAG(zebra_flags, ZEBRA_FLAG_BLACKHOLE);
+       if (flags & RTF_REJECT) {
+               nh.type = NEXTHOP_TYPE_BLACKHOLE;
+               nh.bh_type = BLACKHOLE_REJECT;
+       } else if (flags & RTF_BLACKHOLE) {
+               nh.type = NEXTHOP_TYPE_BLACKHOLE;
+               nh.bh_type = BLACKHOLE_NULL;
+       }
 
        if (dest.sa.sa_family == AF_INET) {
                struct prefix p;
@@ -1017,11 +1021,12 @@ void rtm_read(struct rt_msghdr *rtm)
                if (rtm->rtm_type == RTM_CHANGE)
                        rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
                                   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
-                                  NULL, 0, 0);
+                                  NULL, NULL, 0, 0);
 
-               memset(&nh, 0, sizeof(nh));
-               nh.type = NEXTHOP_TYPE_IPV4;
-               nh.gate.ipv4 = gate.sin;
+               if (!nh.type) {
+                       nh.type = NEXTHOP_TYPE_IPV4;
+                       nh.gate.ipv4 = gate.sin.sin_addr;
+               }
 
                if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
                    || rtm->rtm_type == RTM_CHANGE)
@@ -1064,11 +1069,12 @@ void rtm_read(struct rt_msghdr *rtm)
                                   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
                                   NULL, NULL, 0, 0);
 
-               memset(&nh, 0, sizeof(nh));
-               nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX
-                                 : NEXTHOP_TYPE_IPV6;
-               nh.gate.ipv6 = gate.sin6;
-               nh.ifindex = ifindex;
+               if (!nh.type) {
+                       nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX
+                                         : NEXTHOP_TYPE_IPV6;
+                       nh.gate.ipv6 = gate.sin6.sin6_addr;
+                       nh.ifindex = ifindex;
+               }
 
                if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
                    || rtm->rtm_type == RTM_CHANGE)
@@ -1088,7 +1094,7 @@ void rtm_read(struct rt_msghdr *rtm)
  */
 int rtm_write(int message, union sockunion *dest, union sockunion *mask,
              union sockunion *gate, union sockunion *mpls, unsigned int index,
-             int zebra_flags, int metric)
+             enum blackhole_type bh_type, int metric)
 {
        int ret;
        caddr_t pnt;
@@ -1178,11 +1184,16 @@ int rtm_write(int message, union sockunion *dest, union sockunion *mask,
        /* Tagging route with flags */
        msg.rtm.rtm_flags |= (RTF_PROTO1);
 
-       /* Additional flags. */
-       if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
-               msg.rtm.rtm_flags |= RTF_BLACKHOLE;
-       if (zebra_flags & ZEBRA_FLAG_REJECT)
+       switch (bh_type) {
+       case BLACKHOLE_UNSPEC:
+               break;
+       case BLACKHOLE_REJECT:
                msg.rtm.rtm_flags |= RTF_REJECT;
+               break;
+       default:
+               msg.rtm.rtm_flags |= RTF_BLACKHOLE;
+               break;
+       }
 
 
 #define SOCKADDRSET(X, R)                                                      \
index 41b322185f5d0fc11b0c9021a8305a73cb50a05a..096a21f78238cb8181fe6097f6ccab40639167f8 100644 (file)
@@ -34,8 +34,8 @@ extern void rtm_read(struct rt_msghdr *);
 extern int ifam_read(struct ifa_msghdr *);
 extern int ifm_read(struct if_msghdr *);
 extern int rtm_write(int, union sockunion *, union sockunion *,
-                    union sockunion *, union sockunion *, unsigned int, int,
-                    int);
+                    union sockunion *, union sockunion *, unsigned int,
+                    enum blackhole_type, int);
 extern const struct message rtm_type_str[];
 
 #endif /* __ZEBRA_KERNEL_SOCKET_H */
index 9e456e436f09bb3ce30fb39dfd7b9542b9477d46..9b1ce23b082e3ca4f19895cac08f47f7308df82b 100644 (file)
@@ -231,7 +231,8 @@ typedef enum {
 
 extern struct nexthop *route_entry_nexthop_ifindex_add(struct route_entry *,
                                                       ifindex_t);
-extern struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *);
+extern struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *,
+                                                        enum blackhole_type);
 extern struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *,
                                                    struct in_addr *,
                                                    struct in_addr *);
index ec19c53b7350dbac33eca0f93affa76c78d23d90..fa38c21abfa928b8c9dbd60b228bd490d1022963 100644 (file)
@@ -1221,7 +1221,7 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
        struct sockaddr_nl snl;
        struct nexthop *nexthop = NULL;
        unsigned int nexthop_num;
-       int discard;
+       int discard = 0;
        int family = PREFIX_FAMILY(p);
        const char *routedesc;
        int setsrc = 0;
@@ -1252,24 +1252,23 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
        req.r.rtm_src_len = src_p ? src_p->prefixlen : 0;
        req.r.rtm_protocol = get_rt_proto(re->type);
        req.r.rtm_scope = RT_SCOPE_UNIVERSE;
+       req.r.rtm_type = RTN_UNICAST;
 
-       if ((re->flags & ZEBRA_FLAG_BLACKHOLE)
-           || (re->flags & ZEBRA_FLAG_REJECT))
+       if (re->nexthop_num == 1
+           && re->nexthop->type == NEXTHOP_TYPE_BLACKHOLE) {
                discard = 1;
-       else
-               discard = 0;
-
-       if (cmd == RTM_NEWROUTE) {
-               if (discard) {
-                       if (re->flags & ZEBRA_FLAG_BLACKHOLE)
-                               req.r.rtm_type = RTN_BLACKHOLE;
-                       else if (re->flags & ZEBRA_FLAG_REJECT)
-                               req.r.rtm_type = RTN_UNREACHABLE;
-                       else
-                               assert(RTN_BLACKHOLE
-                                      != RTN_UNREACHABLE); /* false */
-               } else
-                       req.r.rtm_type = RTN_UNICAST;
+
+               switch (re->nexthop->bh_type) {
+               case BLACKHOLE_ADMINPROHIB:
+                       req.r.rtm_type = RTN_PROHIBIT;
+                       break;
+               case BLACKHOLE_REJECT:
+                       req.r.rtm_type = RTN_UNREACHABLE;
+                       break;
+               default:
+                       req.r.rtm_type = RTN_BLACKHOLE;
+                       break;
+               }
        }
 
        addattr_l(&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen);
@@ -1294,6 +1293,9 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
                addattr32(&req.n, sizeof req, RTA_TABLE, re->table);
        }
 
+       if (discard)
+               goto skip;
+
        if (re->mtu || re->nexthop_mtu) {
                char buf[NL_PKT_BUF_SIZE];
                struct rtattr *rta = (void *)buf;
@@ -1307,21 +1309,6 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
                          RTA_PAYLOAD(rta));
        }
 
-       if (discard) {
-               if (cmd == RTM_NEWROUTE)
-                       for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
-                               /* We shouldn't encounter recursive nexthops on
-                                * discard routes,
-                                * but it is probably better to handle that case
-                                * correctly anyway.
-                                */
-                               if (CHECK_FLAG(nexthop->flags,
-                                              NEXTHOP_FLAG_RECURSIVE))
-                                       continue;
-                       }
-               goto skip;
-       }
-
        /* Count overall nexthops so we can decide whether to use singlepath
         * or multipath case. */
        nexthop_num = 0;
index 32ae41b917cd77496efd9a4e7cc63561bba311b5..10c71091946e9175b54923803d53432cf29e8396 100644 (file)
 
 extern struct zebra_privs_t zserv_privs;
 
-/* kernel socket export */
-extern int rtm_write(int message, union sockunion *dest, union sockunion *mask,
-                    union sockunion *gate, union sockunion *mpls,
-                    unsigned int index, int zebra_flags, int metric);
-
 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
 /* Adjust netmask socket length. Return value is a adjusted sin_len
    value. */
@@ -108,6 +103,7 @@ static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct route_entry *re)
        int gate = 0;
        int error;
        char prefix_buf[PREFIX_STRLEN];
+       enum blackhole_type bh_type = BLACKHOLE_UNSPEC;
 
        if (IS_ZEBRA_DEBUG_RIB)
                prefix2str(p, prefix_buf, sizeof(prefix_buf));
@@ -155,6 +151,7 @@ static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct route_entry *re)
                                struct in_addr loopback;
                                loopback.s_addr = htonl(INADDR_LOOPBACK);
                                sin_gate.sin_addr = loopback;
+                               bh_type = nexthop->bh_type;
                                gate = 1;
                        }
 
@@ -182,7 +179,7 @@ static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct route_entry *re)
                                cmd, (union sockunion *)&sin_dest,
                                (union sockunion *)mask,
                                gate ? (union sockunion *)&sin_gate : NULL,
-                               smplsp, ifindex, re->flags, re->metric);
+                               smplsp, ifindex, bh_type, re->metric);
 
                        if (IS_ZEBRA_DEBUG_RIB) {
                                if (!gate) {
@@ -292,6 +289,7 @@ static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re)
        ifindex_t ifindex = 0;
        int gate = 0;
        int error;
+       enum blackhole_type bh_type = BLACKHOLE_UNSPEC;
 
        memset(&sin_dest, 0, sizeof(struct sockaddr_in6));
        sin_dest.sin6_family = AF_INET6;
@@ -331,6 +329,9 @@ static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re)
                            || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
                                ifindex = nexthop->ifindex;
 
+                       if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE)
+                               bh_type = nexthop->bh_type;
+
                        if (cmd == RTM_ADD)
                                SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
                }
@@ -369,7 +370,7 @@ static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re)
                error = rtm_write(cmd, (union sockunion *)&sin_dest,
                                  (union sockunion *)mask,
                                  gate ? (union sockunion *)&sin_gate : NULL,
-                                 smplsp, ifindex, re->flags, re->metric);
+                                 smplsp, ifindex, bh_type, re->metric);
 
 #if 0
       if (error)
index 28f795663939aa4250cba15bb3174be33c294266..27c789137263b48533a4d92068d510dbab50d947 100644 (file)
@@ -222,7 +222,6 @@ static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd,
                                   rib_dest_t *dest, struct route_entry *re)
 {
        struct nexthop *nexthop;
-       int discard;
 
        memset(ri, 0, sizeof(*ri));
 
@@ -247,30 +246,9 @@ static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd,
        }
 
        ri->rtm_protocol = netlink_proto_from_route_type(re->type);
-
-       if ((re->flags & ZEBRA_FLAG_BLACKHOLE)
-           || (re->flags & ZEBRA_FLAG_REJECT))
-               discard = 1;
-       else
-               discard = 0;
-
-       if (cmd == RTM_NEWROUTE) {
-               if (discard) {
-                       if (re->flags & ZEBRA_FLAG_BLACKHOLE)
-                               ri->rtm_type = RTN_BLACKHOLE;
-                       else if (re->flags & ZEBRA_FLAG_REJECT)
-                               ri->rtm_type = RTN_UNREACHABLE;
-                       else
-                               assert(0);
-               } else
-                       ri->rtm_type = RTN_UNICAST;
-       }
-
+       ri->rtm_type = RTN_UNICAST;
        ri->metric = &re->metric;
 
-       if (discard)
-               return 1;
-
        for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
                if (ri->num_nhs >= multipath_num)
                        break;
@@ -278,6 +256,22 @@ static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd,
                if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
                        continue;
 
+               if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) {
+                       switch (nexthop->bh_type) {
+                       case BLACKHOLE_ADMINPROHIB:
+                               ri->rtm_type = RTN_PROHIBIT;
+                               break;
+                       case BLACKHOLE_REJECT:
+                               ri->rtm_type = RTN_UNREACHABLE;
+                               break;
+                       case BLACKHOLE_NULL:
+                       default:
+                               ri->rtm_type = RTN_BLACKHOLE;
+                               break;
+                       }
+                       return 1;
+               }
+
                if ((cmd == RTM_NEWROUTE
                     && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
                    || (cmd == RTM_DELROUTE
index 450ad5b0bffc7bc70ac4e2c2dd1ab84bd0ee848d..b850f1fb1e12f3ad3c862a9199c3c2b700273c93 100644 (file)
@@ -141,7 +141,6 @@ static Fpm__AddRoute *create_add_route_message(qpb_allocator_t *allocator,
                                               struct route_entry *re)
 {
        Fpm__AddRoute *msg;
-       int discard;
        struct nexthop *nexthop;
        uint num_nhs, u;
        struct nexthop *nexthops[MULTIPATH_NUM];
@@ -164,26 +163,7 @@ static Fpm__AddRoute *create_add_route_message(qpb_allocator_t *allocator,
        msg->sub_address_family = QPB__SUB_ADDRESS_FAMILY__UNICAST;
        msg->key = fpm_route_key_create(allocator, rib_dest_prefix(dest));
        qpb_protocol_set(&msg->protocol, re->type);
-
-       if ((re->flags & ZEBRA_FLAG_BLACKHOLE)
-           || (re->flags & ZEBRA_FLAG_REJECT))
-               discard = 1;
-       else
-               discard = 0;
-
-       if (discard) {
-               if (re->flags & ZEBRA_FLAG_BLACKHOLE) {
-                       msg->route_type = FPM__ROUTE_TYPE__BLACKHOLE;
-               } else if (re->flags & ZEBRA_FLAG_REJECT) {
-                       msg->route_type = FPM__ROUTE_TYPE__UNREACHABLE;
-               } else {
-                       assert(0);
-               }
-               return msg;
-       } else {
-               msg->route_type = FPM__ROUTE_TYPE__NORMAL;
-       }
-
+       msg->route_type = FPM__ROUTE_TYPE__NORMAL;
        msg->metric = re->metric;
 
        /*
@@ -197,6 +177,19 @@ static Fpm__AddRoute *create_add_route_message(qpb_allocator_t *allocator,
                if (num_nhs >= ZEBRA_NUM_OF(nexthops))
                        break;
 
+               if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) {
+                       switch (nexthop->bh_type) {
+                       case BLACKHOLE_REJECT:
+                               msg->route_type = FPM__ROUTE_TYPE__UNREACHABLE;
+                               break;
+                       case BLACKHOLE_NULL:
+                       default:
+                               msg->route_type = FPM__ROUTE_TYPE__BLACKHOLE;
+                               break;
+                       }
+                       return msg;
+               }
+
                if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
                        continue;
 
index 644f48793ab627582a060459c0d8c9c40537747e..eecefa09c8cb087d7856b07be51198077c0853db 100644 (file)
@@ -291,13 +291,14 @@ struct nexthop *route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re,
        return nexthop;
 }
 
-struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *re)
+struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *re,
+                                                  enum blackhole_type bh_type)
 {
        struct nexthop *nexthop;
 
        nexthop = nexthop_new();
        nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
-       SET_FLAG(re->flags, ZEBRA_FLAG_BLACKHOLE);
+       nexthop->bh_type = bh_type;
 
        route_entry_nexthop_add(re, nexthop);
 
@@ -471,12 +472,6 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
                        continue;
                }
 
-               /* If the longest prefix match for the nexthop yields
-                * a blackhole, mark it as inactive. */
-               if (CHECK_FLAG(match->flags, ZEBRA_FLAG_BLACKHOLE)
-                   || CHECK_FLAG(match->flags, ZEBRA_FLAG_REJECT))
-                       return 0;
-
                if (match->type == ZEBRA_ROUTE_CONNECT) {
                        /* Directly point connected route. */
                        newhop = match->nexthop;
@@ -488,41 +483,46 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
                        return 1;
                } else if (CHECK_FLAG(re->flags, ZEBRA_FLAG_INTERNAL)) {
                        resolved = 0;
-                       for (ALL_NEXTHOPS(match->nexthop, newhop))
-                               if (CHECK_FLAG(newhop->flags, NEXTHOP_FLAG_FIB)
-                                   && !CHECK_FLAG(newhop->flags,
-                                                  NEXTHOP_FLAG_RECURSIVE)) {
-                                       if (set) {
-                                               SET_FLAG(
-                                                       nexthop->flags,
-                                                       NEXTHOP_FLAG_RECURSIVE);
-                                               SET_FLAG(
-                                                       re->status,
-                                                       ROUTE_ENTRY_NEXTHOPS_CHANGED);
-
-                                               nexthop_set_resolved(
-                                                       afi, newhop, nexthop);
-                                       }
-                                       resolved = 1;
+                       for (ALL_NEXTHOPS(match->nexthop, newhop)) {
+                               if (newhop->type == NEXTHOP_TYPE_BLACKHOLE)
+                                       continue;
+                               if (!CHECK_FLAG(newhop->flags,
+                                               NEXTHOP_FLAG_FIB))
+                                       continue;
+                               if (CHECK_FLAG(newhop->flags,
+                                              NEXTHOP_FLAG_RECURSIVE))
+                                       continue;
+
+                               if (set) {
+                                       SET_FLAG(nexthop->flags,
+                                                NEXTHOP_FLAG_RECURSIVE);
+                                       SET_FLAG(re->status,
+                                                ROUTE_ENTRY_NEXTHOPS_CHANGED);
+                                       nexthop_set_resolved(afi, newhop,
+                                                            nexthop);
                                }
+                               resolved = 1;
+                       }
                        if (resolved && set)
                                re->nexthop_mtu = match->mtu;
                        return resolved;
                } else if (re->type == ZEBRA_ROUTE_STATIC) {
                        resolved = 0;
-                       for (ALL_NEXTHOPS(match->nexthop, newhop))
-                               if (CHECK_FLAG(newhop->flags,
-                                              NEXTHOP_FLAG_FIB)) {
-                                       if (set) {
-                                               SET_FLAG(
-                                                       nexthop->flags,
-                                                       NEXTHOP_FLAG_RECURSIVE);
+                       for (ALL_NEXTHOPS(match->nexthop, newhop)) {
+                               if (newhop->type == NEXTHOP_TYPE_BLACKHOLE)
+                                       continue;
+                               if (!CHECK_FLAG(newhop->flags,
+                                               NEXTHOP_FLAG_FIB))
+                                       continue;
 
-                                               nexthop_set_resolved(
-                                                       afi, newhop, nexthop);
-                                       }
-                                       resolved = 1;
+                               if (set) {
+                                       SET_FLAG(nexthop->flags,
+                                                NEXTHOP_FLAG_RECURSIVE);
+                                       nexthop_set_resolved(afi, newhop,
+                                                            nexthop);
                                }
+                               resolved = 1;
+                       }
                        if (resolved && set)
                                re->nexthop_mtu = match->mtu;
                        return resolved;
index 6815916faf8d08b91e232f6b0d80be2b30e8d51f..51bbf2a0cc5e66c5beeaa25e5ed80ec1ebf9e4db 100644 (file)
@@ -91,7 +91,8 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
                                                                  si->ifindex);
                        break;
                case STATIC_BLACKHOLE:
-                       nexthop = route_entry_nexthop_blackhole_add(re);
+                       nexthop = route_entry_nexthop_blackhole_add(re,
+                                                                   si->bh_type);
                        break;
                case STATIC_IPV6_GATEWAY:
                        nexthop = route_entry_nexthop_ipv6_add(re,
@@ -166,7 +167,8 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
                                                                  si->ifindex);
                        break;
                case STATIC_BLACKHOLE:
-                       nexthop = route_entry_nexthop_blackhole_add(re);
+                       nexthop = route_entry_nexthop_blackhole_add(re,
+                                                                   si->bh_type);
                        break;
                case STATIC_IPV6_GATEWAY:
                        nexthop = route_entry_nexthop_ipv6_add(re,
@@ -187,9 +189,6 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
                                           si->snh_label.num_labels,
                                           &si->snh_label.label[0]);
 
-               /* Save the flags of this static routes (reject, blackhole) */
-               re->flags = si->flags;
-
                if (IS_ZEBRA_DEBUG_RIB) {
                        char buf[INET6_ADDRSTRLEN];
                        if (IS_ZEBRA_DEBUG_RIB) {
@@ -364,7 +363,7 @@ void static_uninstall_route(afi_t afi, safi_t safi, struct prefix *p,
 
 int static_add_route(afi_t afi, safi_t safi, u_char type, struct prefix *p,
                     struct prefix_ipv6 *src_p, union g_addr *gate,
-                    const char *ifname, u_char flags,
+                    const char *ifname, enum blackhole_type bh_type,
                     route_tag_t tag, u_char distance, struct zebra_vrf *zvrf,
                     struct static_nh_label *snh_label)
 {
@@ -405,7 +404,7 @@ int static_add_route(afi_t afi, safi_t safi, u_char type, struct prefix *p,
                        if ((distance == si->distance) && (tag == si->tag)
                            && !memcmp(&si->snh_label, snh_label,
                                       sizeof(struct static_nh_label))
-                           && si->flags == flags) {
+                           && si->bh_type == bh_type) {
                                route_unlock_node(rn);
                                return 0;
                        } else
@@ -424,7 +423,7 @@ int static_add_route(afi_t afi, safi_t safi, u_char type, struct prefix *p,
 
        si->type = type;
        si->distance = distance;
-       si->flags = flags;
+       si->bh_type = bh_type;
        si->tag = tag;
        si->vrf_id = zvrf_id(zvrf);
        if (ifname)
index ff9f0f59e7da5d55ab90584a6a73f34ae77d607b..458594a28951edea3cbae5c8971ee9c8fa7ed995 100644 (file)
@@ -61,18 +61,12 @@ struct static_route {
        /*
         * Nexthop value.
         */
+       enum blackhole_type bh_type;
        union g_addr addr;
        ifindex_t ifindex;
 
        char ifname[INTERFACE_NAMSIZ + 1];
 
-       /* bit flags */
-       u_char flags;
-       /*
-        see ZEBRA_FLAG_REJECT
-            ZEBRA_FLAG_BLACKHOLE
-        */
-
        /* Label information */
        struct static_nh_label snh_label;
 };
@@ -86,7 +80,7 @@ extern void static_uninstall_route(afi_t afi, safi_t safi, struct prefix *p,
 
 extern int static_add_route(afi_t, safi_t safi, u_char type, struct prefix *p,
                            struct prefix_ipv6 *src_p, union g_addr *gate,
-                           const char *ifname, u_char flags,
+                           const char *ifname, enum blackhole_type bh_type,
                            route_tag_t tag, u_char distance,
                            struct zebra_vrf *zvrf,
                            struct static_nh_label *snh_label);
index 9f887e840189428045cfb4d16fd7cd34a3556571..d9ef81e97cc6a44d9eac96d77adb90626039cd12 100644 (file)
@@ -74,7 +74,7 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
        union g_addr gate;
        union g_addr *gatep = NULL;
        struct in_addr mask;
-       u_char flag = 0;
+       enum blackhole_type bh_type = 0;
        route_tag_t tag = 0;
        struct zebra_vrf *zvrf;
        u_char type;
@@ -165,28 +165,18 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
                }
        }
 
-       /* Null0 static route.  */
-       if ((ifname != NULL)
-           && (strncasecmp(ifname, "Null0", strlen(ifname)) == 0)) {
-               if (flag_str) {
-                       vty_out(vty, "%% can not have flag %s with Null0\n",
-                               flag_str);
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-               SET_FLAG(flag, ZEBRA_FLAG_BLACKHOLE);
-               ifname = NULL;
-       }
-
        /* Route flags */
        if (flag_str) {
                switch (flag_str[0]) {
                case 'r':
                case 'R': /* XXX */
-                       SET_FLAG(flag, ZEBRA_FLAG_REJECT);
+                       bh_type = BLACKHOLE_REJECT;
                        break;
+               case 'n':
+               case 'N' /* XXX */:
                case 'b':
                case 'B': /* XXX */
-                       SET_FLAG(flag, ZEBRA_FLAG_BLACKHOLE);
+                       bh_type = BLACKHOLE_NULL;
                        break;
                default:
                        vty_out(vty, "%% Malformed flag %s \n", flag_str);
@@ -221,7 +211,7 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
 
        if (!negate)
                static_add_route(afi, safi, type, &p, src_p, gatep, ifname,
-                                   flag, tag, distance, zvrf, &snh_label);
+                                   bh_type, tag, distance, zvrf, &snh_label);
        else
                static_delete_route(afi, safi, type, &p, src_p, gatep, ifname,
                                    tag, distance, zvrf, &snh_label);
@@ -346,8 +336,7 @@ DEFPY (ip_route,
           <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask>\
           <\
             {A.B.C.D$gate|INTERFACE$ifname}\
-            |null0$ifname\
-            |<reject|blackhole>$flag\
+            |<null0|reject|blackhole>$flag\
           >\
           [{\
             tag (1-4294967295)\
@@ -417,10 +406,6 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
                        vty_out(vty, ", best");
                if (re->refcnt)
                        vty_out(vty, ", refcnt %ld", re->refcnt);
-               if (CHECK_FLAG(re->flags, ZEBRA_FLAG_BLACKHOLE))
-                       vty_out(vty, ", blackhole");
-               if (CHECK_FLAG(re->flags, ZEBRA_FLAG_REJECT))
-                       vty_out(vty, ", reject");
                vty_out(vty, "\n");
 
                if (re->type == ZEBRA_ROUTE_RIP || re->type == ZEBRA_ROUTE_OSPF
@@ -485,7 +470,20 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
                                                       re->vrf_id));
                                break;
                        case NEXTHOP_TYPE_BLACKHOLE:
-                               vty_out(vty, " directly connected, Null0");
+                               vty_out(vty, " unreachable");
+                               switch (nexthop->bh_type) {
+                               case BLACKHOLE_REJECT:
+                                       vty_out(vty, " (ICMP unreachable)");
+                                       break;
+                               case BLACKHOLE_ADMINPROHIB:
+                                       vty_out(vty, " (ICMP admin-prohibited)");
+                                       break;
+                               case BLACKHOLE_NULL:
+                                       vty_out(vty, " (blackhole)");
+                                       break;
+                               case BLACKHOLE_UNSPEC:
+                                       break;
+                               }
                                break;
                        default:
                                break;
@@ -580,12 +578,6 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
                        json_object_int_add(json_route, "metric", re->metric);
                }
 
-               if (CHECK_FLAG(re->flags, ZEBRA_FLAG_BLACKHOLE))
-                       json_object_boolean_true_add(json_route, "blackhole");
-
-               if (CHECK_FLAG(re->flags, ZEBRA_FLAG_REJECT))
-                       json_object_boolean_true_add(json_route, "reject");
-
                if (re->type == ZEBRA_ROUTE_RIP || re->type == ZEBRA_ROUTE_OSPF
                    || re->type == ZEBRA_ROUTE_ISIS
                    || re->type == ZEBRA_ROUTE_NHRP
@@ -671,7 +663,26 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
                                break;
                        case NEXTHOP_TYPE_BLACKHOLE:
                                json_object_boolean_true_add(json_nexthop,
-                                                            "blackhole");
+                                                            "unreachable");
+                               switch (nexthop->bh_type) {
+                               case BLACKHOLE_REJECT:
+                                       json_object_boolean_true_add(
+                                                       json_nexthop,
+                                                       "reject");
+                                       break;
+                               case BLACKHOLE_ADMINPROHIB:
+                                       json_object_boolean_true_add(
+                                                       json_nexthop,
+                                                       "admin-prohibited");
+                                       break;
+                               case BLACKHOLE_NULL:
+                                       json_object_boolean_true_add(
+                                                       json_nexthop,
+                                                       "blackhole");
+                                       break;
+                               case BLACKHOLE_UNSPEC:
+                                       break;
+                               }
                                break;
                        default:
                                break;
@@ -796,7 +807,20 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
                                ifindex2ifname(nexthop->ifindex, re->vrf_id));
                        break;
                case NEXTHOP_TYPE_BLACKHOLE:
-                       vty_out(vty, " is directly connected, Null0");
+                       vty_out(vty, " unreachable");
+                       switch (nexthop->bh_type) {
+                       case BLACKHOLE_REJECT:
+                               vty_out(vty, " (ICMP unreachable)");
+                               break;
+                       case BLACKHOLE_ADMINPROHIB:
+                               vty_out(vty, " (ICMP admin-prohibited)");
+                               break;
+                       case BLACKHOLE_NULL:
+                               vty_out(vty, " (blackhole)");
+                               break;
+                       case BLACKHOLE_UNSPEC:
+                               break;
+                       }
                        break;
                default:
                        break;
@@ -839,11 +863,6 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
                                               sizeof buf, 1));
                }
 
-               if (CHECK_FLAG(re->flags, ZEBRA_FLAG_BLACKHOLE))
-                       vty_out(vty, ", bh");
-               if (CHECK_FLAG(re->flags, ZEBRA_FLAG_REJECT))
-                       vty_out(vty, ", rej");
-
                if (re->type == ZEBRA_ROUTE_RIP || re->type == ZEBRA_ROUTE_OSPF
                    || re->type == ZEBRA_ROUTE_ISIS
                    || re->type == ZEBRA_ROUTE_NHRP
@@ -1693,12 +1712,15 @@ static int static_config(struct vty *vty, afi_t afi, safi_t safi,
                                case STATIC_IFNAME:
                                        vty_out(vty, " %s", si->ifname);
                                        break;
-                               /* blackhole and Null0 mean the same thing */
                                case STATIC_BLACKHOLE:
-                                       if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
+                                       switch (si->bh_type) {
+                                       case BLACKHOLE_REJECT:
                                                vty_out(vty, " reject");
-                                       else
-                                               vty_out(vty, " Null0");
+                                               break;
+                                       default:
+                                               vty_out(vty, " blackhole");
+                                               break;
+                                       }
                                        break;
                                case STATIC_IPV4_GATEWAY_IFNAME:
                                        vty_out(vty, " %s %s",
@@ -1716,19 +1738,6 @@ static int static_config(struct vty *vty, afi_t afi, safi_t safi,
                                        break;
                                }
 
-                               /* flags are incompatible with STATIC_BLACKHOLE
-                                */
-                               if (si->type != STATIC_BLACKHOLE) {
-                                       if (CHECK_FLAG(si->flags,
-                                                      ZEBRA_FLAG_REJECT))
-                                               vty_out(vty, " %s", "reject");
-
-                                       if (CHECK_FLAG(si->flags,
-                                                      ZEBRA_FLAG_BLACKHOLE))
-                                               vty_out(vty, " %s",
-                                                       "blackhole");
-                               }
-
                                if (si->tag)
                                        vty_out(vty, " tag %" ROUTE_TAG_PRI,
                                                si->tag);
@@ -1763,8 +1772,7 @@ DEFPY (ipv6_route,
        "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M]\
           <\
             {X:X::X:X$gate|INTERFACE$ifname}\
-            |null0$ifname\
-            |<reject|blackhole>$flag\
+            |<null0|reject|blackhole>$flag\
           >\
           [{\
             tag (1-4294967295)\
index 0e0cc78bbe3be3267f979a2288b1ff71acef1f33..46dfe378182a4c3c431f16574ad88aca1f951ea2 100644 (file)
@@ -1051,6 +1051,7 @@ static int zread_route_add(struct zserv *client, u_short length,
        struct route_entry *re;
        struct nexthop *nexthop = NULL;
        int i, ret;
+       enum blackhole_type bh_type = BLACKHOLE_NULL;
 
        s = client->ibuf;
        if (zapi_route_decode(s, &api) < 0)
@@ -1093,7 +1094,7 @@ static int zread_route_add(struct zserv *client, u_short length,
                                        api_nh->ifindex);
                                break;
                        case NEXTHOP_TYPE_BLACKHOLE:
-                               route_entry_nexthop_blackhole_add(re);
+                               route_entry_nexthop_blackhole_add(re, bh_type);
                                break;
                        }
 
@@ -1163,7 +1164,7 @@ static int zread_route_del(struct zserv *client, u_short length,
                src_p = &api.src_prefix;
 
        rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
-                  api.flags, &api.prefix, src_p, NULL, 0, zvrf->table_id,
+                  api.flags, &api.prefix, src_p, NULL, zvrf->table_id,
                   api.metric);
 
        /* Stats */
@@ -1201,6 +1202,7 @@ static int zread_ipv4_add(struct zserv *client, u_short length,
        enum lsp_types_t label_type = ZEBRA_LSP_NONE;
        mpls_label_t label;
        struct nexthop *nexthop;
+       enum blackhole_type bh_type = BLACKHOLE_NULL;
 
        /* Get input stream.  */
        s = client->ibuf;
@@ -1264,7 +1266,7 @@ static int zread_ipv4_add(struct zserv *client, u_short length,
                                stream_forward_getp(s, IPV6_MAX_BYTELEN);
                                break;
                        case NEXTHOP_TYPE_BLACKHOLE:
-                               route_entry_nexthop_blackhole_add(re);
+                               route_entry_nexthop_blackhole_add(re, bh_type);
                                break;
                        }
                }
@@ -1329,7 +1331,7 @@ static int zread_ipv4_delete(struct zserv *client, u_short length,
        table_id = zvrf->table_id;
 
        rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance,
-                  api.flags, &p, NULL, NULL, 0, table_id, 0);
+                  api.flags, &p, NULL, NULL, table_id, 0);
        client->v4_route_del_cnt++;
        return 0;
 }
@@ -1367,6 +1369,7 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client,
        enum lsp_types_t label_type = ZEBRA_LSP_NONE;
        mpls_label_t label;
        struct nexthop *nexthop;
+       enum blackhole_type bh_type = BLACKHOLE_NULL;
 
        /* Get input stream.  */
        s = client->ibuf;
@@ -1434,7 +1437,7 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client,
                                }
                                break;
                        case NEXTHOP_TYPE_BLACKHOLE:
-                               route_entry_nexthop_blackhole_add(re);
+                               route_entry_nexthop_blackhole_add(re, bh_type);
                                break;
                        }
                }
@@ -1516,6 +1519,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length,
        enum lsp_types_t label_type = ZEBRA_LSP_NONE;
        mpls_label_t label;
        struct nexthop *nexthop;
+       enum blackhole_type bh_type = BLACKHOLE_NULL;
 
        /* Get input stream.  */
        s = client->ibuf;
@@ -1594,7 +1598,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length,
                                }
                                break;
                        case NEXTHOP_TYPE_BLACKHOLE:
-                               route_entry_nexthop_blackhole_add(re);
+                               route_entry_nexthop_blackhole_add(re, bh_type);
                                break;
                        }
                }
@@ -1689,7 +1693,7 @@ static int zread_ipv6_delete(struct zserv *client, u_short length,
                src_pp = NULL;
 
        rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, api.instance,
-                  api.flags, &p, src_pp, NULL, 0, client->rtm_table, 0);
+                  api.flags, &p, src_pp, NULL, client->rtm_table, 0);
 
        client->v6_route_del_cnt++;
        return 0;