]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_fpm_netlink.c
isisd: implement 'max-area-addresses-mismatch' notification
[mirror_frr.git] / zebra / zebra_fpm_netlink.c
index 060cb693ebe505e84cd1ff0ef0c0bd24f2e98d1c..207cbc0992221a9c2de839ff69a7cf9c23467813 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with GNU Zebra; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <zebra.h>
 
+#ifdef HAVE_NETLINK
+
 #include "log.h"
 #include "rib.h"
 #include "vty.h"
 #include "prefix.h"
 
 #include "zebra/zserv.h"
+#include "zebra/zebra_dplane.h"
 #include "zebra/zebra_ns.h"
 #include "zebra/zebra_vrf.h"
 #include "zebra/kernel_netlink.h"
@@ -44,7 +46,7 @@
  *
  * Returns string representation of an address of the given AF.
  */
-static inline const char *addr_to_a(u_char af, void *addr)
+static inline const char *addr_to_a(uint8_t af, void *addr)
 {
        if (!addr)
                return "<No address>";
@@ -82,7 +84,7 @@ static const char *prefix_addr_to_a(struct prefix *prefix)
  *
  * The size of an address in a given address family.
  */
-static size_t af_addr_size(u_char af)
+static size_t af_addr_size(uint8_t af)
 {
        switch (af) {
 
@@ -124,10 +126,10 @@ typedef struct netlink_nh_info_t_ {
  */
 typedef struct netlink_route_info_t_ {
        uint16_t nlmsg_type;
-       u_char rtm_type;
+       uint8_t rtm_type;
        uint32_t rtm_table;
-       u_char rtm_protocol;
-       u_char af;
+       uint8_t rtm_protocol;
+       uint8_t af;
        struct prefix *prefix;
        uint32_t *metric;
        unsigned int num_nhs;
@@ -148,7 +150,7 @@ typedef struct netlink_route_info_t_ {
  * Returns TRUE if a nexthop was added, FALSE otherwise.
  */
 static int netlink_route_info_add_nh(netlink_route_info_t *ri,
-                                    struct nexthop *nexthop, int recursive)
+                                    struct nexthop *nexthop)
 {
        netlink_nh_info_t nhi;
        union g_addr *src;
@@ -159,7 +161,7 @@ static int netlink_route_info_add_nh(netlink_route_info_t *ri,
        if (ri->num_nhs >= (int)ZEBRA_NUM_OF(ri->nhs))
                return 0;
 
-       nhi.recursive = recursive;
+       nhi.recursive = nexthop->rparent ? 1 : 0;
        nhi.type = nexthop->type;
        nhi.if_index = nexthop->ifindex;
 
@@ -198,7 +200,7 @@ static int netlink_route_info_add_nh(netlink_route_info_t *ri,
 /*
  * netlink_proto_from_route_type
  */
-static u_char netlink_proto_from_route_type(int type)
+static uint8_t netlink_proto_from_route_type(int type)
 {
        switch (type) {
        case ZEBRA_ROUTE_KERNEL:
@@ -218,11 +220,9 @@ static u_char netlink_proto_from_route_type(int type)
  * Returns TRUE on success and FALSE on failure.
  */
 static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd,
-                                  rib_dest_t *dest, struct rib *rib)
+                                  rib_dest_t *dest, struct route_entry *re)
 {
-       struct nexthop *nexthop, *tnexthop;
-       int recursing;
-       int discard;
+       struct nexthop *nexthop;
 
        memset(ri, 0, sizeof(*ri));
 
@@ -237,52 +237,47 @@ static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd,
         * An RTM_DELROUTE need not be accompanied by any nexthops,
         * particularly in our communication with the FPM.
         */
-       if (cmd == RTM_DELROUTE && !rib)
+       if (cmd == RTM_DELROUTE && !re)
                return 1;
 
-       if (!rib) {
-               zfpm_debug("%s: Expected non-NULL rib pointer",
+       if (!re) {
+               zfpm_debug("%s: Expected non-NULL re pointer",
                           __PRETTY_FUNCTION__);
                return 0;
        }
 
-       ri->rtm_protocol = netlink_proto_from_route_type(rib->type);
-
-       if ((rib->flags & ZEBRA_FLAG_BLACKHOLE)
-           || (rib->flags & ZEBRA_FLAG_REJECT))
-               discard = 1;
-       else
-               discard = 0;
-
-       if (cmd == RTM_NEWROUTE) {
-               if (discard) {
-                       if (rib->flags & ZEBRA_FLAG_BLACKHOLE)
-                               ri->rtm_type = RTN_BLACKHOLE;
-                       else if (rib->flags & ZEBRA_FLAG_REJECT)
-                               ri->rtm_type = RTN_UNREACHABLE;
-                       else
-                               assert(0);
-               } else
-                       ri->rtm_type = RTN_UNICAST;
-       }
-
-       ri->metric = &rib->metric;
+       ri->rtm_protocol = netlink_proto_from_route_type(re->type);
+       ri->rtm_type = RTN_UNICAST;
+       ri->metric = &re->metric;
 
-       if (discard)
-               return 1;
-
-       for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) {
+       for (ALL_NEXTHOPS(re->ng, nexthop)) {
                if (ri->num_nhs >= multipath_num)
                        break;
 
                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
                        && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))) {
-                       netlink_route_info_add_nh(ri, nexthop, recursing);
+                       netlink_route_info_add_nh(ri, nexthop);
                }
        }
 
@@ -445,17 +440,19 @@ static void zfpm_log_route_info(netlink_route_info_t *ri, const char *label)
  * Returns the number of bytes written to the buffer. 0 or a negative
  * value indicates an error.
  */
-int zfpm_netlink_encode_route(int cmd, rib_dest_t *dest, struct rib *rib,
+int zfpm_netlink_encode_route(int cmd, rib_dest_t *dest, struct route_entry *re,
                              char *in_buf, size_t in_buf_len)
 {
        netlink_route_info_t ri_space, *ri;
 
        ri = &ri_space;
 
-       if (!netlink_route_info_fill(ri, cmd, dest, rib))
+       if (!netlink_route_info_fill(ri, cmd, dest, re))
                return 0;
 
        zfpm_log_route_info(ri, __FUNCTION__);
 
        return netlink_route_info_encode(ri, in_buf, in_buf_len);
 }
+
+#endif /* HAVE_NETLINK */