]> git.proxmox.com Git - mirror_frr.git/blobdiff - ldpd/ldp_zebra.c
Merge pull request #3069 from donaldsharp/bgp_nexthop_address
[mirror_frr.git] / ldpd / ldp_zebra.c
index f7d715e81c67bf9318ab40447e6373c3dd9591e2..c8b775cb8e8bf96416a8703cf9aa52a62fbb198b 100644 (file)
@@ -1,22 +1,20 @@
 /*
  * Copyright (C) 2016 by Open Source Routing.
  *
- * This file is part of GNU Zebra.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
+ * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * 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.
+ * 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>
@@ -68,7 +66,7 @@ ifp2kif(struct interface *ifp, struct kif *kif)
        kif->ifindex = ifp->ifindex;
        kif->operative = if_is_operative(ifp);
        if (ifp->ll_type == ZEBRA_LLT_ETHER)
-               memcpy(kif->mac, ifp->hw_addr, ETHER_ADDR_LEN);
+               memcpy(kif->mac, ifp->hw_addr, ETH_ALEN);
 }
 
 static void
@@ -144,9 +142,9 @@ zebra_send_mpls_labels(int cmd, struct kroute *kr)
                stream_put_in_addr(s, &kr->nexthop.v4);
                break;
        case AF_INET6:
-               stream_write(s, (u_char *)&kr->prefix.v6, 16);
+               stream_write(s, (uint8_t *)&kr->prefix.v6, 16);
                stream_putc(s, kr->prefixlen);
-               stream_write(s, (u_char *)&kr->nexthop.v6, 16);
+               stream_write(s, (uint8_t *)&kr->nexthop.v6, 16);
                break;
        default:
                fatalx("kr_change: unknown af");
@@ -214,13 +212,14 @@ kmpw_unset(struct zapi_pw *zpw)
 void
 kif_redistribute(const char *ifname)
 {
-       struct listnode         *node, *cnode;
+       struct vrf              *vrf = vrf_lookup_by_id(VRF_DEFAULT);
+       struct listnode         *cnode;
        struct interface        *ifp;
        struct connected        *ifc;
        struct kif               kif;
        struct kaddr             ka;
 
-       for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+       FOR_ALL_INTERFACES (vrf, ifp) {
                if (ifname && strcmp(ifname, ifp->name) != 0)
                        continue;
 
@@ -289,7 +288,7 @@ ldp_interface_delete(int command, struct zclient *zclient, zebra_size_t length,
 
        /* To support pseudo interface do not free interface structure.  */
        /* if_delete(ifp); */
-       ifp->ifindex = IFINDEX_DELETED;
+       if_set_index(ifp, IFINDEX_INTERNAL);
 
        ifp2kif(ifp, &kif);
        main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
@@ -398,19 +397,34 @@ static int
 ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
     vrf_id_t vrf_id)
 {
-       struct stream           *s;
-       u_char                   type;
-       u_char                   message_flags;
+       struct zapi_route        api;
+       struct zapi_nexthop     *api_nh;
        struct kroute            kr;
-       int                      nhnum = 0, nhlen;
-       size_t                   nhmark;
-       int                      add = 0;
+       int                      i, add = 0;
+
+       if (zapi_route_decode(zclient->ibuf, &api) < 0)
+               return -1;
+
+       /* we completely ignore srcdest routes for now. */
+       if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
+               return (0);
 
        memset(&kr, 0, sizeof(kr));
-       s = zclient->ibuf;
+       kr.af = api.prefix.family;
+       switch (kr.af) {
+       case AF_INET:
+               kr.prefix.v4 = api.prefix.u.prefix4;
+               break;
+       case AF_INET6:
+               kr.prefix.v6 = api.prefix.u.prefix6;
+               break;
+       default:
+               break;
+       }
+       kr.prefixlen = api.prefix.prefixlen;
+       kr.priority = api.distance;
 
-       type = stream_getc(s);
-       switch (type) {
+       switch (api.type) {
        case ZEBRA_ROUTE_CONNECT:
                kr.flags |= F_CONNECTED;
                break;
@@ -421,84 +435,58 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
                break;
        }
 
-       stream_getl(s); /* flags, unused */
-       stream_getw(s); /* instance, unused */
-       message_flags = stream_getc(s);
-
-       switch (command) {
-       case ZEBRA_REDISTRIBUTE_IPV4_ADD:
-       case ZEBRA_REDISTRIBUTE_IPV4_DEL:
-               kr.af = AF_INET;
-               nhlen = sizeof(struct in_addr);
-               break;
-       case ZEBRA_REDISTRIBUTE_IPV6_ADD:
-       case ZEBRA_REDISTRIBUTE_IPV6_DEL:
-               kr.af = AF_INET6;
-               nhlen = sizeof(struct in6_addr);
-               break;
-       default:
-               fatalx("ldp_zebra_read_route: unknown command");
-       }
-       kr.prefixlen = stream_getc(s);
-       stream_get(&kr.prefix, s, PSIZE(kr.prefixlen));
-
        if (bad_addr(kr.af, &kr.prefix) ||
            (kr.af == AF_INET6 && IN6_IS_SCOPE_EMBED(&kr.prefix.v6)))
                return (0);
 
-       if (kr.af == AF_INET6 &&
-           CHECK_FLAG(message_flags, ZAPI_MESSAGE_SRCPFX)) {
-               uint8_t src_prefixlen;
-
-               src_prefixlen = stream_getc(s);
-
-               /* we completely ignore srcdest routes for now. */
-               if (src_prefixlen)
-                       return (0);
-       }
-
-       if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_NEXTHOP)) {
-               nhnum = stream_getc(s);
-               nhmark = stream_get_getp(s);
-               stream_set_getp(s, nhmark + nhnum * (nhlen + 5));
-       }
-
-       if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_DISTANCE))
-               kr.priority = stream_getc(s);
-       if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_METRIC))
-               stream_getl(s); /* metric, not used */
-
-       if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_NEXTHOP))
-               stream_set_getp(s, nhmark);
-
-       if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD ||
-           command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
+       if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
                add = 1;
 
-       if (nhnum == 0)
+       if (api.nexthop_num == 0)
                debug_zebra_in("route %s %s/%d (%s)", (add) ? "add" : "delete",
                    log_addr(kr.af, &kr.prefix), kr.prefixlen,
-                   zebra_route_string(type));
+                   zebra_route_string(api.type));
 
        /* loop through all the nexthops */
-       for (; nhnum > 0; nhnum--) {
-               switch (kr.af) {
-               case AF_INET:
-                       kr.nexthop.v4.s_addr = stream_get_ipv4(s);
+       for (i = 0; i < api.nexthop_num; i++) {
+               api_nh = &api.nexthops[i];
+               switch (api_nh->type) {
+               case NEXTHOP_TYPE_IPV4:
+                       if (kr.af != AF_INET)
+                               continue;
+                       kr.nexthop.v4 = api_nh->gate.ipv4;
+                       kr.ifindex = 0;
                        break;
-               case AF_INET6:
-                       stream_get(&kr.nexthop.v6, s, sizeof(kr.nexthop.v6));
+               case NEXTHOP_TYPE_IPV4_IFINDEX:
+                       if (kr.af != AF_INET)
+                               continue;
+                       kr.nexthop.v4 = api_nh->gate.ipv4;
+                       kr.ifindex = api_nh->ifindex;
                        break;
-               default:
+               case NEXTHOP_TYPE_IPV6:
+                       if (kr.af != AF_INET6)
+                               continue;
+                       kr.nexthop.v6 = api_nh->gate.ipv6;
+                       kr.ifindex = 0;
+                       break;
+               case NEXTHOP_TYPE_IPV6_IFINDEX:
+                       if (kr.af != AF_INET6)
+                               continue;
+                       kr.nexthop.v6 = api_nh->gate.ipv6;
+                       kr.ifindex = api_nh->ifindex;
                        break;
+               case NEXTHOP_TYPE_IFINDEX:
+                       if (!(kr.flags & F_CONNECTED))
+                               continue;
+                       break;
+               default:
+                       continue;
                }
-               stream_getc(s); /* ifindex_num, unused. */
-               kr.ifindex = stream_getl(s);
 
                debug_zebra_in("route %s %s/%d nexthop %s ifindex %u (%s)",
                    (add) ? "add" : "delete", log_addr(kr.af, &kr.prefix),
                    kr.prefixlen, log_addr(kr.af, &kr.nexthop), kr.ifindex,
-                   zebra_route_string(type));
+                   zebra_route_string(api.type));
 
                if (add)
                        main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr,
@@ -539,12 +527,14 @@ ldp_zebra_connected(struct zclient *zclient)
            ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT);
 }
 
+extern struct zebra_privs_t ldpd_privs;
+
 void
 ldp_zebra_init(struct thread_master *master)
 {
        /* Set default values. */
-       zclient = zclient_new(master);
-       zclient_init(zclient, ZEBRA_ROUTE_LDP, 0);
+       zclient = zclient_new_notify(master, &zclient_options_default);
+       zclient_init(zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs);
 
        /* set callbacks */
        zclient->zebra_connected = ldp_zebra_connected;
@@ -555,10 +545,8 @@ ldp_zebra_init(struct thread_master *master)
        zclient->interface_down = ldp_interface_status_change;
        zclient->interface_address_add = ldp_interface_address_add;
        zclient->interface_address_delete = ldp_interface_address_delete;
-       zclient->redistribute_route_ipv4_add = ldp_zebra_read_route;
-       zclient->redistribute_route_ipv4_del = ldp_zebra_read_route;
-       zclient->redistribute_route_ipv6_add = ldp_zebra_read_route;
-       zclient->redistribute_route_ipv6_del = ldp_zebra_read_route;
+       zclient->redistribute_route_add = ldp_zebra_read_route;
+       zclient->redistribute_route_del = ldp_zebra_read_route;
        zclient->pw_status_update = ldp_zebra_read_pw_status_update;
 }