]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_zebra.c
bgpd: Convert binfo to path
[mirror_frr.git] / bgpd / bgp_zebra.c
index 3434717484ae586b2393f1f03fe00259abd030fd..1c0553344b0db6d80fecba25ca1d10a6dfce3fd3 100644 (file)
@@ -229,8 +229,6 @@ static int bgp_interface_delete(int command, struct zclient *zclient,
        struct bgp *bgp;
 
        bgp = bgp_lookup_by_vrf_id(vrf_id);
-       if (!bgp)
-               return 0;
 
        s = zclient->ibuf;
        ifp = zebra_interface_state_read(s, vrf_id);
@@ -240,7 +238,8 @@ static int bgp_interface_delete(int command, struct zclient *zclient,
        if (BGP_DEBUG(zebra, ZEBRA))
                zlog_debug("Rx Intf del VRF %u IF %s", vrf_id, ifp->name);
 
-       bgp_update_interface_nbrs(bgp, ifp, NULL);
+       if (bgp)
+               bgp_update_interface_nbrs(bgp, ifp, NULL);
 
        if_set_index(ifp, IFINDEX_INTERNAL);
        return 0;
@@ -257,8 +256,6 @@ static int bgp_interface_up(int command, struct zclient *zclient,
        struct bgp *bgp;
 
        bgp = bgp_lookup_by_vrf_id(vrf_id);
-       if (!bgp)
-               return 0;
 
        s = zclient->ibuf;
        ifp = zebra_interface_state_read(s, vrf_id);
@@ -269,6 +266,9 @@ static int bgp_interface_up(int command, struct zclient *zclient,
        if (BGP_DEBUG(zebra, ZEBRA))
                zlog_debug("Rx Intf up VRF %u IF %s", vrf_id, ifp->name);
 
+       if (!bgp)
+               return 0;
+
        for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
                bgp_connected_add(bgp, c);
 
@@ -287,10 +287,9 @@ static int bgp_interface_down(int command, struct zclient *zclient,
        struct nbr_connected *nc;
        struct listnode *node, *nnode;
        struct bgp *bgp;
+       struct peer *peer;
 
        bgp = bgp_lookup_by_vrf_id(vrf_id);
-       if (!bgp)
-               return 0;
 
        s = zclient->ibuf;
        ifp = zebra_interface_state_read(s, vrf_id);
@@ -300,6 +299,9 @@ static int bgp_interface_down(int command, struct zclient *zclient,
        if (BGP_DEBUG(zebra, ZEBRA))
                zlog_debug("Rx Intf down VRF %u IF %s", vrf_id, ifp->name);
 
+       if (!bgp)
+               return 0;
+
        for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
                bgp_connected_delete(bgp, c);
 
@@ -307,11 +309,7 @@ static int bgp_interface_down(int command, struct zclient *zclient,
                bgp_nbr_connected_delete(bgp, nc, 1);
 
        /* Fast external-failover */
-       {
-               struct peer *peer;
-
-               if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
-                       return 0;
+       if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) {
 
                for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
 #if defined(HAVE_CUMULUS)
@@ -345,8 +343,6 @@ static int bgp_interface_address_add(int command, struct zclient *zclient,
        struct bgp *bgp;
 
        bgp = bgp_lookup_by_vrf_id(vrf_id);
-       if (!bgp)
-               return 0;
 
        ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
 
@@ -360,6 +356,9 @@ static int bgp_interface_address_add(int command, struct zclient *zclient,
                           ifc->ifp->name, buf);
        }
 
+       if (!bgp)
+               return 0;
+
        if (if_is_operative(ifc->ifp)) {
                bgp_connected_add(bgp, ifc);
 
@@ -382,8 +381,6 @@ static int bgp_interface_address_delete(int command, struct zclient *zclient,
        struct bgp *bgp;
 
        bgp = bgp_lookup_by_vrf_id(vrf_id);
-       if (!bgp)
-               return 0;
 
        ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
 
@@ -397,7 +394,7 @@ static int bgp_interface_address_delete(int command, struct zclient *zclient,
                           ifc->ifp->name, buf);
        }
 
-       if (if_is_operative(ifc->ifp)) {
+       if (bgp && if_is_operative(ifc->ifp)) {
                bgp_connected_delete(bgp, ifc);
        }
 
@@ -474,6 +471,7 @@ static int bgp_interface_vrf_update(int command, struct zclient *zclient,
        struct nbr_connected *nc;
        struct listnode *node, *nnode;
        struct bgp *bgp;
+       struct peer *peer;
 
        ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id,
                                              &new_vrf_id);
@@ -485,28 +483,23 @@ static int bgp_interface_vrf_update(int command, struct zclient *zclient,
                           ifp->name, new_vrf_id);
 
        bgp = bgp_lookup_by_vrf_id(vrf_id);
-       if (!bgp)
-               return 0;
 
-       for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
-               bgp_connected_delete(bgp, c);
+       if (bgp) {
+               for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c))
+                       bgp_connected_delete(bgp, c);
 
-       for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc))
-               bgp_nbr_connected_delete(bgp, nc, 1);
+               for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc))
+                       bgp_nbr_connected_delete(bgp, nc, 1);
 
-       /* Fast external-failover */
-       {
-               struct peer *peer;
-
-               if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
-                       return 0;
-
-               for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
-                       if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
-                               continue;
+               /* Fast external-failover */
+               if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) {
+                       for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+                               if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
+                                       continue;
 
-                       if (ifp == peer->nexthop.ifp)
-                               BGP_EVENT_ADD(peer, BGP_Stop);
+                               if (ifp == peer->nexthop.ifp)
+                                       BGP_EVENT_ADD(peer, BGP_Stop);
+                       }
                }
        }
 
@@ -777,8 +770,9 @@ static int if_get_ipv4_address(struct interface *ifp, struct in_addr *addr)
        return 0;
 }
 
-int bgp_nexthop_set(union sockunion *local, union sockunion *remote,
-                   struct bgp_nexthop *nexthop, struct peer *peer)
+
+bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
+                          struct bgp_nexthop *nexthop, struct peer *peer)
 {
        int ret = 0;
        struct interface *ifp = NULL;
@@ -786,9 +780,9 @@ int bgp_nexthop_set(union sockunion *local, union sockunion *remote,
        memset(nexthop, 0, sizeof(struct bgp_nexthop));
 
        if (!local)
-               return -1;
+               return false;
        if (!remote)
-               return -1;
+               return false;
 
        if (local->sa.sa_family == AF_INET) {
                nexthop->v4 = local->sin.sin_addr;
@@ -815,8 +809,24 @@ int bgp_nexthop_set(union sockunion *local, union sockunion *remote,
                                                      peer->bgp->vrf_id);
        }
 
-       if (!ifp)
-               return -1;
+       if (!ifp) {
+               /*
+                * BGP views do not currently get proper data
+                * from zebra( when attached ) to be able to
+                * properly resolve nexthops, so give this
+                * instance type a pass.
+                */
+               if (peer->bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
+                       return true;
+               /*
+                * If we have no interface data but we have established
+                * some connection w/ zebra than something has gone
+                * terribly terribly wrong here, so say this failed
+                * If we do not any zebra connection then not
+                * having a ifp pointer is ok.
+                */
+               return zclient_num_connects ? false : true;
+       }
 
        nexthop->ifp = ifp;
 
@@ -912,11 +922,11 @@ int bgp_nexthop_set(union sockunion *local, union sockunion *remote,
 
        /* If we have identified the local interface, there is no error for now.
         */
-       return 0;
+       return true;
 }
 
-static struct in6_addr *bgp_info_to_ipv6_nexthop(struct bgp_info *info,
-                                                ifindex_t *ifindex)
+static struct in6_addr *
+bgp_path_info_to_ipv6_nexthop(struct bgp_path_info *info, ifindex_t *ifindex)
 {
        struct in6_addr *nexthop = NULL;
 
@@ -958,7 +968,7 @@ static struct in6_addr *bgp_info_to_ipv6_nexthop(struct bgp_info *info,
 }
 
 static int bgp_table_map_apply(struct route_map *map, struct prefix *p,
-                              struct bgp_info *info)
+                              struct bgp_path_info *info)
 {
        route_map_result_t ret;
 
@@ -984,7 +994,7 @@ static int bgp_table_map_apply(struct route_map *map, struct prefix *p,
                        ifindex_t ifindex;
                        struct in6_addr *nexthop;
 
-                       nexthop = bgp_info_to_ipv6_nexthop(info, &ifindex);
+                       nexthop = bgp_path_info_to_ipv6_nexthop(info, &ifindex);
                        zlog_debug(
                                "Zebra rmap deny: IPv6 route %s/%d nexthop %s",
                                inet_ntop(AF_INET6, &p->u.prefix6, buf[0],
@@ -1078,8 +1088,8 @@ int bgp_zebra_get_table_range(uint32_t chunk_size,
                return -1;
        ret = tm_get_table_chunk(zclient, chunk_size, start, end);
        if (ret < 0) {
-               flog_err(BGP_ERR_TABLE_CHUNK,
-                         "BGP: Error getting table chunk %u", chunk_size);
+               flog_err(EC_BGP_TABLE_CHUNK,
+                        "BGP: Error getting table chunk %u", chunk_size);
                return -1;
        }
        zlog_info("BGP: Table Manager returns range from chunk %u is [%u %u]",
@@ -1111,13 +1121,11 @@ static int update_ipv4nh_for_route_install(int nh_othervrf,
        return 1;
 }
 
-static int update_ipv6nh_for_route_install(int nh_othervrf,
-                                          struct in6_addr *nexthop,
-                                          ifindex_t ifindex,
-                                          struct bgp_info *ri,
-                                          struct bgp_info *best_ri,
-                                          bool is_evpn,
-                                          struct zapi_nexthop *api_nh)
+static int
+update_ipv6nh_for_route_install(int nh_othervrf, struct in6_addr *nexthop,
+                               ifindex_t ifindex, struct bgp_path_info *ri,
+                               struct bgp_path_info *best_ri, bool is_evpn,
+                               struct zapi_nexthop *api_nh)
 {
        struct attr *attr;
 
@@ -1173,7 +1181,7 @@ static int update_ipv6nh_for_route_install(int nh_othervrf,
 }
 
 void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
-                       struct bgp_info *info, struct bgp *bgp, afi_t afi,
+                       struct bgp_path_info *info, struct bgp *bgp, afi_t afi,
                        safi_t safi)
 {
        struct zapi_route api;
@@ -1183,11 +1191,11 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
        int has_valid_label = 0;
        uint8_t distance;
        struct peer *peer;
-       struct bgp_info *mpinfo;
+       struct bgp_path_info *mpinfo;
        uint32_t metric;
        struct attr local_attr;
-       struct bgp_info local_info;
-       struct bgp_info *mpinfo_cp = &local_info;
+       struct bgp_path_info local_info;
+       struct bgp_path_info *mpinfo_cp = &local_info;
        route_tag_t tag;
        mpls_label_t label;
        int nh_othervrf = 0;
@@ -1232,7 +1240,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
 
                /* Obtain peer from parent */
                if (info->extra && info->extra->parent)
-                       peer = ((struct bgp_info *)(info->extra->parent))->peer;
+                       peer = ((struct bgp_path_info *)(info->extra->parent))
+                                      ->peer;
        }
 
        tag = info->attr->tag;
@@ -1256,7 +1265,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
 
        /* Metric is currently based on the best-path only */
        metric = info->attr->med;
-       for (mpinfo = info; mpinfo; mpinfo = bgp_info_mpath_next(mpinfo)) {
+       for (mpinfo = info; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) {
                if (valid_nh_count >= multipath_num)
                        break;
 
@@ -1346,8 +1355,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
                                        tag = mpinfo_cp->attr->tag;
                                }
                        }
-                       nexthop = bgp_info_to_ipv6_nexthop(mpinfo_cp,
-                                                          &ifindex);
+                       nexthop = bgp_path_info_to_ipv6_nexthop(mpinfo_cp,
+                                                               &ifindex);
                        nh_updated = update_ipv6nh_for_route_install(
                                        nh_othervrf, nexthop, ifindex,
                                        mpinfo, info, is_evpn, api_nh);
@@ -1456,7 +1465,7 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)
 {
        struct bgp_node *rn;
        struct bgp_table *table;
-       struct bgp_info *ri;
+       struct bgp_path_info *ri;
 
        /* Don't try to install if we're not connected to Zebra or Zebra doesn't
         * know of this instance.
@@ -1470,7 +1479,7 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)
 
        for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
                for (ri = rn->info; ri; ri = ri->next)
-                       if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED) &&
+                       if (CHECK_FLAG(ri->flags, BGP_PATH_SELECTED) &&
 
                            (ri->type == ZEBRA_ROUTE_BGP
                             && (ri->sub_type == BGP_ROUTE_NORMAL
@@ -1480,7 +1489,7 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)
                                                   safi);
 }
 
-void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info,
+void bgp_zebra_withdraw(struct prefix *p, struct bgp_path_info *info,
                        struct bgp *bgp, safi_t safi)
 {
        struct zapi_route api;
@@ -1570,14 +1579,20 @@ static void bgp_redist_del(struct bgp *bgp, afi_t afi, uint8_t type,
                listnode_delete(bgp->redist[afi][type], red);
                XFREE(MTYPE_BGP_REDIST, red);
                if (!bgp->redist[afi][type]->count)
-                       list_delete_and_null(&bgp->redist[afi][type]);
+                       list_delete(&bgp->redist[afi][type]);
        }
 }
 
 /* Other routes redistribution into BGP. */
 int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type,
-                        unsigned short instance)
+                        unsigned short instance, bool changed)
 {
+       /* If redistribute options are changed call
+        * bgp_redistribute_unreg() to reset the option and withdraw
+        * the routes
+        */
+       if (changed)
+               bgp_redistribute_unreg(bgp, afi, type, instance);
 
        /* Return if already redistribute flag is set. */
        if (instance) {
@@ -1664,7 +1679,7 @@ int bgp_redistribute_metric_set(struct bgp *bgp, struct bgp_redist *red,
                                afi_t afi, int type, uint32_t metric)
 {
        struct bgp_node *rn;
-       struct bgp_info *ri;
+       struct bgp_path_info *ri;
 
        if (red->redist_metric_flag && red->redist_metric == metric)
                return 0;
@@ -1687,8 +1702,8 @@ int bgp_redistribute_metric_set(struct bgp *bgp, struct bgp_redist *red,
                                ri->attr = bgp_attr_intern(&new_attr);
                                bgp_attr_unintern(&old_attr);
 
-                               bgp_info_set_flag(rn, ri,
-                                                 BGP_INFO_ATTR_CHANGED);
+                               bgp_path_info_set_flag(rn, ri,
+                                                      BGP_PATH_ATTR_CHANGED);
                                bgp_process(bgp, rn, afi, SAFI_UNICAST);
                        }
                }
@@ -2065,20 +2080,20 @@ static int ipset_entry_notify_owner(int command, struct zclient *zclient,
                break;
        case ZAPI_IPSET_ENTRY_INSTALLED:
                {
-                       struct bgp_info *bgp_info;
-                       struct bgp_info_extra *extra;
-
-                       bgp_pbime->installed = true;
-                       bgp_pbime->install_in_progress = false;
-                       if (BGP_DEBUG(zebra, ZEBRA))
-                               zlog_debug("%s: Received IPSET_ENTRY_INSTALLED",
-                                          __PRETTY_FUNCTION__);
-                       /* link bgp_info to bpme */
-                       bgp_info = (struct bgp_info *)bgp_pbime->bgp_info;
-                       extra = bgp_info_extra_get(bgp_info);
-                       if (extra->bgp_fs_pbr == NULL)
-                               extra->bgp_fs_pbr = list_new();
-                       listnode_add(extra->bgp_fs_pbr, bgp_pbime);
+               struct bgp_path_info *path;
+               struct bgp_path_info_extra *extra;
+
+               bgp_pbime->installed = true;
+               bgp_pbime->install_in_progress = false;
+               if (BGP_DEBUG(zebra, ZEBRA))
+                       zlog_debug("%s: Received IPSET_ENTRY_INSTALLED",
+                                  __PRETTY_FUNCTION__);
+               /* link bgp_path_info to bpme */
+               path = (struct bgp_path_info *)bgp_pbime->path;
+               extra = bgp_path_info_extra_get(path);
+               if (extra->bgp_fs_pbr == NULL)
+                       extra->bgp_fs_pbr = list_new();
+               listnode_add(extra->bgp_fs_pbr, bgp_pbime);
                }
                break;
        case ZAPI_IPSET_ENTRY_FAIL_REMOVE:
@@ -2175,8 +2190,6 @@ static void bgp_encode_pbr_ipset_match(struct stream *s,
 
        stream_put(s, pbim->ipset_name,
                   ZEBRA_IPSET_NAME_SIZE);
-
-
 }
 
 static void bgp_encode_pbr_ipset_entry_match(struct stream *s,
@@ -2374,7 +2387,8 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient,
        int ipa_len;
        char buf[ETHER_ADDR_STRLEN];
        char buf1[INET6_ADDRSTRLEN];
-       uint8_t flags;
+       uint8_t flags = 0;
+       uint32_t seqnum = 0;
 
        memset(&ip, 0, sizeof(ip));
        s = zclient->ibuf;
@@ -2383,10 +2397,10 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient,
        ipa_len = stream_getl(s);
        if (ipa_len != 0 && ipa_len != IPV4_MAX_BYTELEN
            && ipa_len != IPV6_MAX_BYTELEN) {
-               flog_err(BGP_ERR_MACIP_LEN,
-                         "%u:Recv MACIP %s with invalid IP addr length %d",
-                         vrf_id, (command == ZEBRA_MACIP_ADD) ? "Add" : "Del",
-                         ipa_len);
+               flog_err(EC_BGP_MACIP_LEN,
+                        "%u:Recv MACIP %s with invalid IP addr length %d",
+                        vrf_id, (command == ZEBRA_MACIP_ADD) ? "Add" : "Del",
+                        ipa_len);
                return -1;
        }
 
@@ -2395,20 +2409,24 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient,
                        (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4 : IPADDR_V6;
                stream_get(&ip.ip.addr, s, ipa_len);
        }
-       flags = stream_getc(s);
+       if (command == ZEBRA_MACIP_ADD) {
+               flags = stream_getc(s);
+               seqnum = stream_getl(s);
+       }
 
        bgp = bgp_lookup_by_vrf_id(vrf_id);
        if (!bgp)
                return 0;
 
        if (BGP_DEBUG(zebra, ZEBRA))
-               zlog_debug("%u:Recv MACIP %s flags 0x%x MAC %s IP %s VNI %u",
+               zlog_debug("%u:Recv MACIP %s flags 0x%x MAC %s IP %s VNI %u seq %u",
                           vrf_id, (command == ZEBRA_MACIP_ADD) ? "Add" : "Del",
                           flags, prefix_mac2str(&mac, buf, sizeof(buf)),
-                          ipaddr2str(&ip, buf1, sizeof(buf1)), vni);
+                          ipaddr2str(&ip, buf1, sizeof(buf1)), vni, seqnum);
 
        if (command == ZEBRA_MACIP_ADD)
-               return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip, flags);
+               return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip,
+                                               flags, seqnum);
        else
                return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip);
 }
@@ -2476,13 +2494,13 @@ static void bgp_zebra_process_label_chunk(
        STREAM_GETL(s, last);
 
        if (zclient->redist_default != proto) {
-               flog_err(BGP_ERR_LM_ERROR, "Got LM msg with wrong proto %u",
-                         proto);
+               flog_err(EC_BGP_LM_ERROR, "Got LM msg with wrong proto %u",
+                        proto);
                return;
        }
        if (zclient->instance != instance) {
-               flog_err(BGP_ERR_LM_ERROR, "Got LM msg with wrong instance %u",
-                         proto);
+               flog_err(EC_BGP_LM_ERROR, "Got LM msg with wrong instance %u",
+                        proto);
                return;
        }
 
@@ -2490,8 +2508,8 @@ static void bgp_zebra_process_label_chunk(
                first < MPLS_LABEL_UNRESERVED_MIN ||
                last > MPLS_LABEL_UNRESERVED_MAX) {
 
-               flog_err(BGP_ERR_LM_ERROR, "%s: Invalid Label chunk: %u - %u",
-                         __func__, first, last);
+               flog_err(EC_BGP_LM_ERROR, "%s: Invalid Label chunk: %u - %u",
+                        __func__, first, last);
                return;
        }
        if (BGP_DEBUG(zebra, ZEBRA)) {
@@ -2507,7 +2525,7 @@ stream_failure:           /* for STREAM_GETX */
 
 extern struct zebra_privs_t bgpd_privs;
 
-void bgp_zebra_init(struct thread_master *master)
+void bgp_zebra_init(struct thread_master *master, unsigned short instance)
 {
        zclient_num_connects = 0;
 
@@ -2546,6 +2564,7 @@ void bgp_zebra_init(struct thread_master *master)
        zclient->ipset_notify_owner = ipset_notify_owner;
        zclient->ipset_entry_notify_owner = ipset_entry_notify_owner;
        zclient->iptable_notify_owner = iptable_notify_owner;
+       zclient->instance = instance;
 }
 
 void bgp_zebra_destroy(void)